From 23b2dcaf82e9e87ac554f117d39b9b99b02a46a6 Mon Sep 17 00:00:00 2001 From: Michael Sippel <micha@fragmental.art> Date: Mon, 3 Feb 2025 17:05:19 +0100 Subject: [PATCH] posint morph code size benchmark --- morphisms/Makefile | 22 ++++++- morphisms/posint-dec-to-hex-generated.c | 82 +++++++++++++++++++++++++ morphisms/posint-dec-to-hex-optimal.c | 47 ++++++++++++++ morphisms/test.c | 55 ----------------- 4 files changed, 149 insertions(+), 57 deletions(-) create mode 100644 morphisms/posint-dec-to-hex-generated.c create mode 100644 morphisms/posint-dec-to-hex-optimal.c delete mode 100644 morphisms/test.c diff --git a/morphisms/Makefile b/morphisms/Makefile index 3912ac9..6526bf8 100644 --- a/morphisms/Makefile +++ b/morphisms/Makefile @@ -6,8 +6,26 @@ all: $(TARGETS) lib/libmorph_%.so: src/%.c $(CC) -O3 -shared -o $@ -fPIC -Iinclude $< -test: test.c lib/libmorph_length-prefix.so lib/libmorph_posint.so - $(CC) -O3 -L$(LIB_DIR) -o $@ -Iinclude $< -lmorph_length-prefix -lmorph_posint +posint-dec-to-hex-generated-gcc: posint-dec-to-hex-generated.c + gcc -g -Os -flto -o $@ -Iinclude $< src/length-prefix.c src/posint.c + +posint-dec-to-hex-generated-clang: posint-dec-to-hex-generated.c + clang -g -Os -flto -o $@ -Iinclude $< src/length-prefix.c src/posint.c + +posint-dec-to-hex-optimal-gcc: posint-dec-to-hex-optimal.c + gcc -g -Os -flto -o $@ $< + +posint-dec-to-hex-optimal-clang: posint-dec-to-hex-optimal.c + clang -g -Os -flto -o $@ $< + +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) clean: rm $(TARGETS) diff --git a/morphisms/posint-dec-to-hex-generated.c b/morphisms/posint-dec-to-hex-generated.c new file mode 100644 index 0000000..f1aa7cf --- /dev/null +++ b/morphisms/posint-dec-to-hex-generated.c @@ -0,0 +1,82 @@ +#include <stdio.h> +#include <stdint.h> +#include <morphisms/length-prefix.h> +#include <morphisms/posint.h> + +int main() { + uint8_t bufA[1024]; + uint8_t bufB[1024]; + + scanf("%s", bufA); + + // morph to + // ℕ ~ <PosInt 10 BigEndian> ~ [~<LengthPrefix x86.UInt64> <Digit 10> ~ Char ~ Ascii] + { + char const * src = (void*) bufA; + struct LengthPrefixUInt8Array * dst = (void*) bufB; + morph_string_as_nullterm_to_length_prefix( src, dst ); + } + + // morph to + // ℕ ~ <PosInt 10 BigEndian> ~ [~<LengthPrefix x86.UInt64> <Digit 10> ~ ℤ_10 ~ x86.UInt64] + { + struct LengthPrefixUInt8Array * src = (void*) bufB; + struct LengthPrefixUInt64Array * dst = (void*) bufA; + + 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 to + // ℕ ~ <PosInt 16 BigEndian> ~ [~<LengthPrefix x86.UInt64> <Digit 16> ~ Char ~ Ascii] + { + struct LengthPrefixUInt64Array * src = (void*) bufB; + struct LengthPrefixUInt8Array * dst = (void*) bufA; + + 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 + // ℕ ~ <PosInt 16 BigEndian> ~ [~<ValueDelim '\0'> <Digit 16> ~ Char ~ Ascii] + { + struct LengthPrefixUInt8Array * src = (void*) bufA; + char * dst = (void*) bufB; + morph_string_as_length_prefix_to_nullterm( src, dst ); + } + + printf("%s\n", bufB); + + return 0; +} diff --git a/morphisms/posint-dec-to-hex-optimal.c b/morphisms/posint-dec-to-hex-optimal.c new file mode 100644 index 0000000..7118ae0 --- /dev/null +++ b/morphisms/posint-dec-to-hex-optimal.c @@ -0,0 +1,47 @@ +#include <stdio.h> +#include <stdint.h> + +int main() { + char bufA[1024]; + char bufB[1024]; + + char * in = bufA; + 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; + } + + printf("%s\n", out); + + return 0; +} diff --git a/morphisms/test.c b/morphisms/test.c deleted file mode 100644 index 1346287..0000000 --- a/morphisms/test.c +++ /dev/null @@ -1,55 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <morphisms/length-prefix.h> -#include <morphisms/posint.h> - -int main( int argc, char * argv[] ) { - char * int1 = malloc(4096); - struct LengthPrefixUInt8Array * int2 = malloc(4096); - struct LengthPrefixUInt64Array * int3 = malloc(4096); - struct LengthPrefixUInt64Array * int4 = malloc(4096); - struct LengthPrefixUInt64Array * int5 = malloc(4096); - struct LengthPrefixUInt64Array * int6 = malloc(4096); - struct LengthPrefixUInt8Array * int7 = malloc(4096); - char * int8 = malloc(4096); - - // ℕ ~ <PosInt 10 BigEndian> ~ [~<ValueDelim '\0'> <Digit 10> ~ Char ~ Ascii] - scanf("%s", int1); - - // morph to - // ℕ ~ <PosInt 10 BigEndian> ~ [~<LengthPrefix x86.UInt64> <Digit 10> ~ Char ~ Ascii] - morph_string_as_nullterm_to_length_prefix( int1, int2 ); - - // morph to - // ℕ ~ <PosInt 10 BigEndian> ~ [~<LengthPrefix x86.UInt64> <Digit 10> ~ ℤ_10 ~ x86.UInt64] - int3->len = int2->len; - for( uint64_t i = 0; i < int2->len; ++i ) - morph_digit_as_char_to_uint64( &int2->items[i], &int3->items[i] ); - - // morph to - // ℕ ~ <PosInt 10 LittleEndian> ~ [~<LengthPrefix x86.UInt64> <Digit 10> ~ ℤ_10 ~ x86.UInt64] - morph_posint_endianness( 10, int3, int4 ); - - // morph to - // ℕ ~ <PosInt 16 LittleEndian> ~ [~<LengthPrefix x86.UInt64> <Digit 16> ~ ℤ_16 ~ x86.UInt64] - morph_posint_radix( 10, 16, int4, int5 ); - - // morph to - // ℕ ~ <PosInt 16 BigEndian> ~ [~<LengthPrefix x86.UInt64> <Digit 16> ~ ℤ_16 ~ x86.UInt64] - morph_posint_endianness( 16, int5, int6 ); - - // morph to - // ℕ ~ <PosInt 16 BigEndian> ~ [~<LengthPrefix x86.UInt64> <Digit 16> ~ Char ~ Ascii] - int7->len = int6->len; - for( uint64_t i = 0; i < int6->len; ++i ) - morph_digit_as_uint64_to_char( &int6->items[i], &int7->items[i] ); - - // morph to - // ℕ ~ <PosInt 16 BigEndian> ~ [~<ValueDelim '\0'> <Digit 16> ~ Char ~ Ascii] - morph_string_as_length_prefix_to_nullterm( int7, int8 ); - - printf("%s\n", int8); - - return 0; -}