From 1f9a9bdc21f1325044c98bb47f32b02ba128d4ef Mon Sep 17 00:00:00 2001 From: doyle Date: Sat, 1 Jul 2023 22:32:50 +1000 Subject: [PATCH] perfaware/part2: Extract the strings containing the haversine points --- build.bat | 3 ++ part2/haversine.c | 65 +++++++++++++++++++++++++++++++++---- part2/haversine_generator.c | 9 +++-- part2/haversine_stdlib.c | 22 +++++++++++++ part2/haversine_stdlib.h | 14 ++++++-- 5 files changed, 102 insertions(+), 11 deletions(-) diff --git a/build.bat b/build.bat index 0dbfe51..282f053 100644 --- a/build.bat +++ b/build.bat @@ -321,4 +321,7 @@ REM Build ====================================================================== pushd %part2_build_dir% cl %part2_dir%\haversine_generator.c /W4 /WX /Z7 /nologo /Fe:haversine_generator_debug || exit /b 1 cl %part2_dir%\haversine_generator.c /W4 /WX /Z7 /nologo /O2 /Fe:haversine_generator_release || exit /b 1 + +cl %part2_dir%\haversine.c /W4 /WX /Z7 /nologo /Fe:haversine_debug || exit /b 1 +cl %part2_dir%\haversine.c /W4 /WX /Z7 /nologo /O2 /Fe:haversine_release || exit /b 1 popd diff --git a/part2/haversine.c b/part2/haversine.c index ad2b822..e21abdb 100644 --- a/part2/haversine.c +++ b/part2/haversine.c @@ -8,6 +8,26 @@ #include #include "listing_0065_haversine_formula.cpp" +typedef struct Str8FindResult { + bool found; + HAV_Str8 match; + HAV_Str8 match_to_end_of_buffer; +} Str8FindResult; + +Str8FindResult FindFirstCharThatLooksLikeANumber(HAV_Str8 buffer) +{ + Str8FindResult result = {0}; + for (size_t index = 0; !result.found && index < buffer.size; index++) { + if (HAV_CharIsDigit(buffer.data[index]) || buffer.data[index] == '+' || buffer.data[index] == '-') { + result.found = true; + result.match = (HAV_Str8){.data = buffer.data + index, .size = 1}; + result.match_to_end_of_buffer = (HAV_Str8){.data = result.match.data, .size = buffer.size - index}; + break; + } + } + return result; +} + #define PRINT_USAGE HAV_PrintLnFmt("Usage: %s [haversine_input.json] [answers.f64]", argv[0]) int main(int argc, char **argv) { @@ -20,15 +40,48 @@ int main(int argc, char **argv) HAV_Str8 arg_json = {argv[1], strlen(argv[1])}; HAV_Str8 arg_answers = {0}; - if (argc == 3) { - arg_answers = {.data = argv[2], .size = strlen(argv[2])}; + if (argc == 3) + arg_answers = (HAV_Str8){.data = argv[2], .size = strlen(argv[2])}; + + HAV_Buffer buffer = HAV_FileRead(arg_json.data); + if (!HAV_BufferIsValid(buffer)) + return 0; + + size_t pair_count = 0; + HAV_Str8 json_it = (HAV_Str8){.data = buffer.data, .size = buffer.size}; + for (;; pair_count++) { + HAV_Str8BinarySplitResult x0_key = HAV_Str8_BinarySplit(json_it, HAV_STR8("x0")); + if (!x0_key.rhs.size) + break; + + Str8FindResult x0_find_value = FindFirstCharThatLooksLikeANumber(x0_key.rhs); + HAV_Str8BinarySplitResult x0_value = HAV_Str8_BinarySplit(x0_find_value.match_to_end_of_buffer, HAV_STR8(",")); + + HAV_Str8BinarySplitResult y0_key = HAV_Str8_BinarySplit(x0_value.rhs, HAV_STR8("y0")); + Str8FindResult y0_find_value = FindFirstCharThatLooksLikeANumber(y0_key.rhs); + HAV_Str8BinarySplitResult y0_value = HAV_Str8_BinarySplit(y0_find_value.match_to_end_of_buffer, HAV_STR8(",")); + + HAV_Str8BinarySplitResult x1_key = HAV_Str8_BinarySplit(y0_value.rhs, HAV_STR8("x1")); + Str8FindResult x1_find_value = FindFirstCharThatLooksLikeANumber(x1_key.rhs); + HAV_Str8BinarySplitResult x1_value = HAV_Str8_BinarySplit(x1_find_value.match_to_end_of_buffer, HAV_STR8(",")); + + HAV_Str8BinarySplitResult y1_key = HAV_Str8_BinarySplit(x1_value.rhs, HAV_STR8("y1")); + Str8FindResult y1_find_value = FindFirstCharThatLooksLikeANumber(y1_key.rhs); + HAV_Str8BinarySplitResult y1_value = HAV_Str8_BinarySplit(y1_find_value.match_to_end_of_buffer, HAV_STR8("}")); + + HAV_PrintLnFmt("{x0: %.*s, y0: %.*s, x1 %.*s, y1: %.*s}", + HAV_STR8_FMT(x0_value.lhs), + HAV_STR8_FMT(y0_value.lhs), + HAV_STR8_FMT(x1_value.lhs), + HAV_STR8_FMT(y1_value.lhs)); + + json_it = y1_value.rhs; } - size_t input_size = 0; - size_t pair_count = 0; - f64 haversine_sum = 0; + size_t input_size = buffer.size; + f64 haversine_sum = 0; f64 reference_haversine_sum = 0; - f64 difference = 0; + f64 difference = 0; HAV_PrintLnFmt("Input size: %zu", input_size); HAV_PrintLnFmt("Pair count: %zu", pair_count); HAV_PrintLnFmt("Haversine sum: %f", haversine_sum); diff --git a/part2/haversine_generator.c b/part2/haversine_generator.c index 568e3ce..6ea5baf 100644 --- a/part2/haversine_generator.c +++ b/part2/haversine_generator.c @@ -99,8 +99,13 @@ int main(int argc, char **argv) uint64_t random_seed = random_seed_u64_result.value; uint64_t rng_state = random_seed; + char json_file_name[1024]; + char answers_file_name[1024]; + snprintf(json_file_name, sizeof(json_file_name), "haversine_%zu_%s_%zu.json", point_count, point_generator == PointGenerator_Cluster ? "cluster" : "uniform", random_seed); + snprintf(answers_file_name, sizeof(json_file_name), "haversine_%zu_%s_%zu.f64", point_count, point_generator == PointGenerator_Cluster ? "cluster" : "uniform", random_seed); + HANDLE haversine_json_file_handle = CreateFile( - /*LPCSTR lpFileName*/ "haversine.json", + /*LPCSTR lpFileName*/ json_file_name, /*DWORD dwDesiredAccess*/ GENERIC_WRITE, /*DWORD dwShareMode*/ 0, /*LPSECURITY_ATTRIBUTES lpSecurityAttributes*/ NULL, @@ -110,7 +115,7 @@ int main(int argc, char **argv) ); HANDLE haversine_f64_file_handle = CreateFile( - /*LPCSTR lpFileName*/ "haversine.f64", + /*LPCSTR lpFileName*/ answers_file_name, /*DWORD dwDesiredAccess*/ GENERIC_WRITE, /*DWORD dwShareMode*/ 0, /*LPSECURITY_ATTRIBUTES lpSecurityAttributes*/ NULL, diff --git a/part2/haversine_stdlib.c b/part2/haversine_stdlib.c index 91bc9d3..8a93d01 100644 --- a/part2/haversine_stdlib.c +++ b/part2/haversine_stdlib.c @@ -27,12 +27,34 @@ HAV_Str8ToU64Result HAV_Str8_ToU64(HAV_Str8 string) return result; } +HAV_Str8BinarySplitResult HAV_Str8_BinarySplit(HAV_Str8 buffer, HAV_Str8 find) +{ + HAV_Str8BinarySplitResult result = {0}; + result.lhs = buffer; + for (size_t index = 0; (index + find.size) <= buffer.size; index++) { + HAV_Str8 check = {buffer.data + index, find.size}; + if (HAV_Str8_Equals(find, check)) { + result.lhs.size = index; + result.rhs.data = check.data + find.size; + result.rhs.size = buffer.size - (index + find.size); + break; + } + } + return result; +} + bool HAV_CharIsWhiteSpace(char ch) { bool result = ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t'; return result; } +bool HAV_CharIsDigit(char ch) +{ + bool result = ch >= '0' && ch <= '9'; + return result; +} + #pragma warning(push) #pragma warning(disable: 4146) // warning C4146: unary minus operator applied to unsigned type, result still unsigned uint32_t HAV_PCG32_Pie (uint64_t *state) diff --git a/part2/haversine_stdlib.h b/part2/haversine_stdlib.h index 858fc90..9fd43c3 100644 --- a/part2/haversine_stdlib.h +++ b/part2/haversine_stdlib.h @@ -15,6 +15,7 @@ #define HAV_ARRAY_UCOUNT(array) sizeof((array)) / sizeof((array)[0]) #define HAV_CAST(Type) (Type) +#define HAV_MIN(a, b) ((a) < (b) ? (a) : (b)) typedef float f32; typedef double f64; @@ -40,13 +41,20 @@ typedef struct HAV_Str8ToU64Result { uint64_t value; } HAV_Str8ToU64Result; +typedef struct HAV_Str8BinarySplitResult { + HAV_Str8 lhs; + HAV_Str8 rhs; +} HAV_Str8BinarySplitResult; + #define HAV_STR8(string) (HAV_Str8){.data = (string), .size = HAV_ARRAY_UCOUNT(string) - 1 } #define HAV_STR8_FMT(string) (int)((string).size), (string).data -bool HAV_Str8_Equals(HAV_Str8 lhs, HAV_Str8 rhs); -HAV_Str8ToU64Result HAV_Str8_ToU64(HAV_Str8 string); +bool HAV_Str8_Equals(HAV_Str8 lhs, HAV_Str8 rhs); +HAV_Str8ToU64Result HAV_Str8_ToU64(HAV_Str8 string); +HAV_Str8BinarySplitResult HAV_Str8_BinarySplit(HAV_Str8 buffer, HAV_Str8 find); -bool HAV_CharIsWhiteSpace(char ch); +bool HAV_CharIsWhiteSpace(char ch); +bool HAV_CharIsDigit(char ch); // NOTE: PCG32 // ============================================================================