From eb29fad4b2649eaf36b599d02ace10e734ef9c58 Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Fri, 14 Feb 2025 13:51:59 +0100 Subject: [PATCH] code size benchmark: separate morph function to avoid overhead from scanf/printf --- morphisms/Makefile | 8 +-- morphisms/posint-dec-to-hex-generated.c | 53 ++++++------------- morphisms/posint-dec-to-hex-optimal.c | 69 +++++++++++++------------ 3 files changed, 56 insertions(+), 74 deletions(-) diff --git a/morphisms/Makefile b/morphisms/Makefile index 439499a..884f9dc 100644 --- a/morphisms/Makefile +++ b/morphisms/Makefile @@ -22,10 +22,10 @@ code-size-benchmark: posint-dec-to-hex-generated-gcc \ posint-dec-to-hex-generated-clang \ posint-dec-to-hex-optimal-gcc \ posint-dec-to-hex-optimal-clang - INST_COUNT_GEN_GCC=$(shell gdb --batch -ex "file posint-dec-to-hex-generated-gcc" -ex "disassemble main" | wc -l) - INST_COUNT_GEN_CLANG=$(shell gdb --batch -ex "file posint-dec-to-hex-generated-clang" -ex "disassemble main" | wc -l) - INST_COUNT_OPT_GCC=$(shell gdb --batch -ex "file posint-dec-to-hex-optimal-gcc" -ex "disassemble main" | wc -l) - INST_COUNT_OPT_CLANG=$(shell gdb --batch -ex "file posint-dec-to-hex-optimal-clang" -ex "disassemble main" | wc -l) + INST_COUNT_GEN_GCC=$(shell gdb --batch -ex "file posint-dec-to-hex-generated-gcc" -ex "disassemble morph_posint_radix" | wc -l) + INST_COUNT_GEN_CLANG=$(shell gdb --batch -ex "file posint-dec-to-hex-generated-clang" -ex "disassemble morph_posint_radix" | wc -l) + INST_COUNT_OPT_GCC=$(shell gdb --batch -ex "file posint-dec-to-hex-optimal-gcc" -ex "disassemble morph_posint_radix" | wc -l) + INST_COUNT_OPT_CLANG=$(shell gdb --batch -ex "file posint-dec-to-hex-optimal-clang" -ex "disassemble posint_radix" | wc -l) clean: rm $(TARGETS) diff --git a/morphisms/posint-dec-to-hex-generated.c b/morphisms/posint-dec-to-hex-generated.c index a942e66..bdba861 100644 --- a/morphisms/posint-dec-to-hex-generated.c +++ b/morphisms/posint-dec-to-hex-generated.c @@ -3,12 +3,11 @@ #include <morphisms/length-prefix.h> #include <morphisms/posint.h> -int main() { - uint8_t bufA[1024]; - uint8_t bufB[1024]; - - scanf("%s", bufA); - +__attribute__((noinline)) +int morph_posint_radix( + uint8_t * bufA, + uint8_t * bufB +) { // morph to // ℕ ~ <PosInt 10 BigEndian> ~ [~<LengthPrefix x86.UInt64> <Digit 10> ~ Char ~ Ascii] { @@ -23,40 +22,14 @@ int main() { struct LengthPrefixUInt8Array * src = (void*) bufB; struct LengthPrefixUInt64Array * dst = (void*) bufA; length_prefix_array_map_8_to_64( morph_digit_as_char_to_uint64, src, dst ); -/* - dst->len = src->len; - for( uint64_t i = 0; i < src->len; ++i ) - morph_digit_as_char_to_uint64( &src->items[i], &dst->items[i] ); -*/ } - - // morph to - // ℕ ~ <PosInt 10 LittleEndian> ~ [~<LengthPrefix x86.UInt64> <Digit 10> ~ ℤ_10 ~ x86.UInt64] - { - uint64_t const radix = 10; - struct LengthPrefixUInt64Array * src = (void*) bufA; - struct LengthPrefixUInt64Array * dst = (void*) bufB; - morph_posint_endianness( radix, src, dst ); - } - - // morph to // ℕ ~ <PosInt 16 LittleEndian> ~ [~<LengthPrefix x86.UInt64> <Digit 16> ~ ℤ_16 ~ x86.UInt64] { uint64_t const src_radix = 10; uint64_t const dst_radix = 16; struct LengthPrefixUInt64Array * src = (void*) bufB; struct LengthPrefixUInt64Array * dst = (void*) bufA; - morph_posint_radix( src_radix, dst_radix, src, dst ); - } - - - // morph to - // ℕ ~ <PosInt 16 LittleEndian> ~ [~<LengthPrefix x86.UInt64> <Digit 10> ~ ℤ_10 ~ x86.UInt64] - { - uint64_t const radix = 16; - struct LengthPrefixUInt64Array * src = (void*) bufA; - struct LengthPrefixUInt64Array * dst = (void*) bufB; - morph_posint_endianness( radix, src, dst ); + morph_posint_radix_little( src_radix, dst_radix, src, dst ); } // morph to @@ -66,11 +39,6 @@ int main() { struct LengthPrefixUInt8Array * dst = (void*) bufA; length_prefix_array_map_64_to_8( morph_digit_as_uint64_to_char, src, dst ); -/* - dst->len = src->len; - for( uint64_t i = 0; i < src->len; ++i ) - morph_digit_as_uint64_to_char( &src->items[i], &dst->items[i] ); -*/ } // morph to @@ -81,6 +49,15 @@ int main() { morph_string_as_length_prefix_to_nullterm( src, dst ); } + return 0; +} + +int main() { + uint8_t bufA[1024]; + uint8_t bufB[1024]; + + scanf("%s", bufA); + morph_posint_radix( bufA, bufB ); printf("%s\n", bufB); return 0; diff --git a/morphisms/posint-dec-to-hex-optimal.c b/morphisms/posint-dec-to-hex-optimal.c index 7118ae0..b9c1ab0 100644 --- a/morphisms/posint-dec-to-hex-optimal.c +++ b/morphisms/posint-dec-to-hex-optimal.c @@ -1,6 +1,42 @@ #include <stdio.h> #include <stdint.h> +__attribute__((noinline)) +int morph_posint_radix( char * in, char * out ) { + uint64_t value = 0; + while( *in ) { + if( *in >= '0' && *in <= '9' ) { + value *= 10; + value += *in - '0'; + } + else + return -1; + + in++; + } + + uint64_t v = value; + while( v ) { + out ++; + v /= 16; + } + + *out-- = '\0'; + while( value ) { + unsigned digit = value % 16; + if( digit < 10 ) { + *out-- = digit + '0'; + } else if( digit < 16 ) { + *out-- = digit + 'a' - 10; + } else { + return -1; + } + value /= 16; + } + + return 0; +} + int main() { char bufA[1024]; char bufB[1024]; @@ -9,38 +45,7 @@ int main() { char * out = bufB; scanf("%s", in); - - uint64_t value = 0; - while( *in ) { - if( *in >= '0' && *in <= '9' ) { - value *= 10; - value += *in - '0'; - } - else - return -1; - - in++; - } - - uint64_t v = value; - while( v ) { - out ++; - v /= 16; - } - - *out-- = '\0'; - while( value ) { - unsigned digit = value % 16; - if( digit < 10 ) { - *out-- = digit + '0'; - } else if( digit < 16 ) { - *out-- = digit + 'a' - 10; - } else { - return -1; - } - value /= 16; - } - + morph_posint_radix( in, out ); printf("%s\n", out); return 0;