implement measuring of how long each step takes
This commit is contained in:
parent
ec61d20b29
commit
b935bfc94f
6
Makefile
6
Makefile
@ -1,4 +1,4 @@
|
||||
CFLAGS=-lm -g -Wall -Walloc-size-larger-than=-1
|
||||
CFLAGS=-lm -g -Wall
|
||||
|
||||
.PHONY := gen_data main
|
||||
|
||||
@ -7,11 +7,11 @@ main: build/main
|
||||
|
||||
build/gen_data: src/gen_data.c
|
||||
mkdir -p build
|
||||
gcc -o build/gen_data src/gen_data.c $(CFLAGS) -O2
|
||||
gcc -o build/gen_data src/gen_data.c $(CFLAGS) -O0
|
||||
|
||||
build/main: src/main.c src/json_parser.c
|
||||
mkdir -p build
|
||||
gcc -o build/main src/main.c $(CFLAGS) -O2
|
||||
gcc -o build/main src/main.c $(CFLAGS) -O0
|
||||
|
||||
clean:
|
||||
rm -r build
|
||||
|
@ -1,3 +1,5 @@
|
||||
# Harvensine computing
|
||||
|
||||
For [Computer, Enhance!](https://www.computerenhance.com/)
|
||||
|
||||
Json spec: https://www.json.org/json-en.html
|
||||
|
@ -139,6 +139,13 @@ static void print_usage(char *program) {
|
||||
fprintf(stderr, "\tcluster <size> <json-output-file> [seed]\n");
|
||||
}
|
||||
|
||||
u64 get_current_time_us()
|
||||
{
|
||||
struct timespec time;
|
||||
clock_gettime(CLOCK_MONOTONIC_RAW, &time);
|
||||
return time.tv_sec * 1000000 + time.tv_nsec / 1000;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
if (argc < 2) {
|
||||
print_usage(argv[0]);
|
||||
@ -197,6 +204,7 @@ int main(int argc, char **argv) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
u64 start_time = get_current_time_us();
|
||||
srand(seed);
|
||||
f64 sum = 0;
|
||||
if (method == GEN_UNIFORM) {
|
||||
@ -246,11 +254,13 @@ int main(int argc, char **argv) {
|
||||
}
|
||||
|
||||
fwrite(&sum, sizeof(f64), 1, answer_file);
|
||||
u64 duration = get_current_time_us() - start_time;
|
||||
|
||||
printf("Used earth radius: %f\n", EARTH_RADIUS);
|
||||
printf("Seed: %d\n", seed);
|
||||
printf("Number of pairs: %d\n", row_count);
|
||||
printf("Expected sum: %lf\n", sum);
|
||||
printf("Duration: %ldus (%lfus/row)\n", duration, ((f64)duration) / row_count);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "json_parser.h"
|
||||
|
||||
@ -339,6 +340,18 @@ int parse_json_bool(bool *result, char *data, size_t data_size)
|
||||
return 0; // TODO:
|
||||
}
|
||||
|
||||
struct json_value *get_json_object_value(struct json_object *obj, char *key, size_t key_size)
|
||||
{
|
||||
for (int i = 0; i < obj->count; i++)
|
||||
{
|
||||
struct json_string *obj_key = obj->keys[i];
|
||||
if (obj_key->size == key_size && !strncmp(obj_key->str, key, key_size)) {
|
||||
return obj->values[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void printf_json_array(struct json_array *array)
|
||||
{
|
||||
|
@ -56,3 +56,5 @@ void printf_json_value(struct json_value *result);
|
||||
void printf_json_string(struct json_string *string);
|
||||
void printf_json_object(struct json_object *object);
|
||||
void printf_json_array(struct json_array *array);
|
||||
|
||||
struct json_value *get_json_object_value(struct json_object *obj, char *key, size_t key_size);
|
||||
|
192
src/main.c
192
src/main.c
@ -1,12 +1,33 @@
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "json_parser.c"
|
||||
|
||||
#define EARTH_RADIUS 6372.8
|
||||
|
||||
typedef uint32_t u32;
|
||||
typedef uint64_t u64;
|
||||
|
||||
struct point_pair {
|
||||
f64 x0;
|
||||
f64 y0;
|
||||
f64 x1;
|
||||
f64 y1;
|
||||
};
|
||||
|
||||
struct point_pairs {
|
||||
struct point_pair *pairs;
|
||||
size_t count;
|
||||
};
|
||||
|
||||
void print_usage(char *program)
|
||||
{
|
||||
printf("Usage: %s <json-file> [test-bin-file]\n", program);
|
||||
printf("Usage: %s <json-file> [reference-bin-file]\n", program);
|
||||
}
|
||||
|
||||
size_t get_file_size(FILE *f)
|
||||
@ -17,9 +38,89 @@ size_t get_file_size(FILE *f)
|
||||
return size;
|
||||
}
|
||||
|
||||
u64 get_current_time_us()
|
||||
{
|
||||
struct timespec time;
|
||||
clock_gettime(CLOCK_MONOTONIC_RAW, &time);
|
||||
return time.tv_sec * 1000000 + time.tv_nsec / 1000;
|
||||
}
|
||||
|
||||
static f64 sqaure_f64(f64 num)
|
||||
{
|
||||
return num*num;
|
||||
}
|
||||
|
||||
static f64 radians_to_degrees(f64 degrees)
|
||||
{
|
||||
return 0.01745329251994329577 * degrees;
|
||||
}
|
||||
|
||||
static f64 get_harvensine_distance(f64 X0, f64 Y0, f64 X1, f64 Y1, f64 earth_radius)
|
||||
{
|
||||
f64 lat1 = Y0;
|
||||
f64 lat2 = Y1;
|
||||
f64 lon1 = X0;
|
||||
f64 lon2 = X1;
|
||||
|
||||
f64 dLat = radians_to_degrees(lat2 - lat1);
|
||||
f64 dLon = radians_to_degrees(lon2 - lon1);
|
||||
lat1 = radians_to_degrees(lat1);
|
||||
lat2 = radians_to_degrees(lat2);
|
||||
|
||||
f64 a = sqaure_f64(sin(dLat/2.0)) + cos(lat1)*cos(lat2)*sqaure_f64(sin(dLon/2));
|
||||
f64 c = 2.0*asin(sqrt(a));
|
||||
|
||||
return earth_radius * c;
|
||||
}
|
||||
|
||||
static struct point_pairs *convert_to_struct(struct json_value *json)
|
||||
{
|
||||
assert(json->type == JSON_TYPE_OBJECT);
|
||||
assert(json->object->count == 1);
|
||||
assert(!strncmp(json->object->keys[0]->str, "pairs", sizeof("pairs")-1));
|
||||
assert(json->object->values[0]->type == JSON_TYPE_ARRAY);
|
||||
struct json_array *pairs_array = json->object->values[0]->array;
|
||||
|
||||
struct point_pairs *result = malloc(sizeof(struct point_pairs));
|
||||
result->pairs = malloc(pairs_array->count * sizeof(struct point_pair));
|
||||
result->count = pairs_array->count;
|
||||
|
||||
for (int i = 0; i < result->count; i++)
|
||||
{
|
||||
assert(pairs_array->values[i]->type == JSON_TYPE_OBJECT);
|
||||
assert(pairs_array->values[i]->object->count == 4);
|
||||
|
||||
struct json_object *json_pair = pairs_array->values[i]->object;
|
||||
struct json_value *x0 = get_json_object_value(json_pair, "x0", sizeof("x0")-1);
|
||||
assert(x0 != NULL && x0->type == JSON_TYPE_NUMBER);
|
||||
struct json_value *y0 = get_json_object_value(json_pair, "y0", sizeof("y0")-1);
|
||||
assert(y0 != NULL && y0->type == JSON_TYPE_NUMBER);
|
||||
struct json_value *x1 = get_json_object_value(json_pair, "x1", sizeof("x1")-1);
|
||||
assert(x1 != NULL && x1->type == JSON_TYPE_NUMBER);
|
||||
struct json_value *y1 = get_json_object_value(json_pair, "y1", sizeof("y1")-1);
|
||||
assert(y1 != NULL && y1->type == JSON_TYPE_NUMBER);
|
||||
|
||||
struct point_pair *pair = &result->pairs[i];
|
||||
pair->x0 = x0->number;
|
||||
pair->y0 = y0->number;
|
||||
pair->x1 = x1->number;
|
||||
pair->y1 = y1->number;
|
||||
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void free_point_pairs(struct point_pairs *pairs)
|
||||
{
|
||||
if (pairs == NULL) return;
|
||||
free(pairs->pairs);
|
||||
free(pairs);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
if (argc < 2) {
|
||||
if (argc <= 1) {
|
||||
print_usage(argv[0]);
|
||||
return -1;
|
||||
}
|
||||
@ -41,13 +142,90 @@ int main(int argc, char **argv)
|
||||
}
|
||||
fclose(f);
|
||||
|
||||
struct json_value *parsed = malloc(sizeof(struct json_value));
|
||||
int bytes_parsed = parse_json_value(parsed, json_data, json_size);
|
||||
f64 *reference_harvensines = NULL;
|
||||
size_t reference_harvensines_count = 0;
|
||||
f64 reference_harvensine_sum = 0;
|
||||
if (argc >= 3)
|
||||
{
|
||||
char *answers_filename = argv[2];
|
||||
FILE *f = fopen(answers_filename, "r");
|
||||
if (f == NULL) {
|
||||
printf("Failed to open: %s\n", json_filename);
|
||||
return -1;
|
||||
}
|
||||
size_t file_size = get_file_size(f);
|
||||
assert(file_size % sizeof(f64) == 0);
|
||||
reference_harvensines_count = file_size / sizeof(f64) - 1;
|
||||
reference_harvensines = malloc(reference_harvensines_count * sizeof(f64));
|
||||
for (int i = 0; i < reference_harvensines_count; i++) {
|
||||
fread(&reference_harvensines[i], sizeof(f64), 1, f);
|
||||
}
|
||||
fread(&reference_harvensine_sum, sizeof(f64), 1, f);
|
||||
|
||||
printf_json_value(parsed);
|
||||
printf("\n");
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
// Step 1. Read json file
|
||||
|
||||
u64 json_parse_duration;
|
||||
struct json_value *parsed = NULL;
|
||||
{
|
||||
parsed = malloc(sizeof(struct json_value));
|
||||
u64 start_time = get_current_time_us();
|
||||
int bytes_parsed = parse_json_value(parsed, json_data, json_size);
|
||||
assert(bytes_parsed >= 0);
|
||||
json_parse_duration = get_current_time_us() - start_time;
|
||||
}
|
||||
|
||||
u32 row_count = parsed->object->values[0]->array->count;
|
||||
if (reference_harvensines_count > 0) {
|
||||
assert(row_count == reference_harvensines_count);
|
||||
}
|
||||
|
||||
printf("Row count: %d\n", row_count);
|
||||
printf("Time to parse JSON: %ldus (%.3lfus/row)\n", json_parse_duration, (f64)json_parse_duration / row_count);
|
||||
|
||||
// Step 2. Convert json object to struct
|
||||
|
||||
u64 struct_convert_duration;
|
||||
struct point_pairs *pairs = NULL;
|
||||
{
|
||||
u64 start_time = get_current_time_us();
|
||||
pairs = convert_to_struct(parsed);
|
||||
struct_convert_duration = get_current_time_us() - start_time;
|
||||
}
|
||||
|
||||
printf("Time to convert to struct: %ldus (%.3lfus/row)\n", struct_convert_duration, (f64)struct_convert_duration / row_count);
|
||||
|
||||
// Step 3. Calculate harvensine distances
|
||||
|
||||
f64 *harvensines = malloc(pairs->count*sizeof(f64));
|
||||
u64 harvensine_duration;
|
||||
{
|
||||
u64 start_time = get_current_time_us();
|
||||
for (int i = 0; i < pairs->count; i++) {
|
||||
struct point_pair *p = &pairs->pairs[i];
|
||||
harvensines[i] = get_harvensine_distance(p->x0, p->y0, p->x1, p->y1, EARTH_RADIUS);
|
||||
}
|
||||
harvensine_duration = get_current_time_us() - start_time;
|
||||
}
|
||||
|
||||
f64 harvensine_sum = 0;
|
||||
for (int i = 0; i < pairs->count; i++) {
|
||||
harvensine_sum += harvensines[i];
|
||||
}
|
||||
|
||||
printf("Time to calc harvensine: %ldus (%.3lfus/row)\n", harvensine_duration, (f64)harvensine_duration / row_count);
|
||||
printf("Sum of all harvensines: %.16f\n", harvensine_sum);
|
||||
|
||||
if (reference_harvensines_count > 0) {
|
||||
printf("Diff of reference harvensine sum: %.16f\n", harvensine_sum - reference_harvensine_sum);
|
||||
}
|
||||
|
||||
free(reference_harvensines);
|
||||
free(harvensines);
|
||||
free_json_value(parsed);
|
||||
free_point_pairs(pairs);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user