diff --git a/haversine_02/compile b/haversine_02/compile index d88b6d4..d0c65d0 100755 --- a/haversine_02/compile +++ b/haversine_02/compile @@ -4,6 +4,12 @@ CC=clang CXX=clang++ CFLAGS="-Wall -Wextra -I$(realpath ./include) " +ASM=nasm +ASM_FLAGS="-f elf64 " + +AR=ar +AR_FLAGS="rcs" + # PARSE ARGUMENTS # From this StackOverflow answer https://stackoverflow.com/a/14203146 while [[ $# > 0 ]];do @@ -71,6 +77,18 @@ MEMTESTOUT=memtest (set -x ; $CC $CFLAGS $MEMTESTSRC -o $MEMTESTOUT) echo +# REPTEST ASSEMBLY +ASM_BUILD_DIR=reptest_build +ASM_SRC="./src/repetition_testing/reptest_functions.asm" +ASM_OBJ="./$ASM_BUILD_DIR/funcs.o" +ASM_LIB="./$ASM_BUILD_DIR/libfuncs.a" + +mkdir $ASM_BUILD_DIR + +(set -x ; $ASM $ASM_FLAGS $ASM_SRC -o $ASM_OBJ) +(set -x ; $AR $AR_FLAGS $ASM_LIB $ASM_OBJ) +echo + if [[ $BASIC_PROFILING == true ]] || [[ $FULL_PROFILING == true ]]; then if [[ $FULL_PROFILING == true ]]; then JSONFLAGS+="-DFULL_PROFILING" @@ -95,7 +113,7 @@ if [[ $BASIC_PROFILING == true ]] || [[ $FULL_PROFILING == true ]]; then cd ../ # REPETITION TESTING - REPTESTSRC="./src/repetition_testing/*.cpp ./$PROF_BUILD_DIR/*.o" + REPTESTSRC="./src/repetition_testing/*.cpp ./$PROF_BUILD_DIR/*.o $ASM_LIB" REPTESTOUT=reptest (set -x ; $CXX $CFLAGS $REPTESTFLAGS $REPTESTSRC -o $REPTESTOUT) @@ -114,4 +132,4 @@ cd ../ echo # CLEAR BUILD FILES -rm -rvf $JSON_BUILD_DIR $PROF_BUILD_DIR +rm -rvf $JSON_BUILD_DIR $PROF_BUILD_DIR $ASM_BUILD_DIR diff --git a/haversine_02/src/repetition_testing/main.cpp b/haversine_02/src/repetition_testing/main.cpp index 8da4980..1c00bf1 100644 --- a/haversine_02/src/repetition_testing/main.cpp +++ b/haversine_02/src/repetition_testing/main.cpp @@ -9,9 +9,18 @@ #define ARR_LEN(ARR) sizeof(ARR) / sizeof(*ARR) +extern "C" void mov_all_bytes_asm(char *buffer, u64 size); +extern "C" void nop_all_bytes_asm(u64 size); +extern "C" void inc_all_bytes_asm(u64 size); +extern "C" void dec_all_bytes_asm(u64 size); + void test_fread(reptester *tester, alloc_type type); void test_read(reptester *tester, alloc_type type); void test_write(reptester *tester, alloc_type type); +void test_write_mov_all_bytes_asm(reptester *tester, alloc_type type); +void test_write_nop_all_bytes_asm(reptester *tester, alloc_type type); +void test_write_inc_all_bytes_asm(reptester *tester, alloc_type type); +void test_write_dec_all_bytes_asm(reptester *tester, alloc_type type); u64 get_file_length(FILE *fp); int main(int argc, char *argv[]) { @@ -65,8 +74,16 @@ int main(int argc, char *argv[]) { func_data funcs[] = { {{"WRITE", "WRITE WITH MALLOC"}, test_write}, - {{"READ", "READ WITH MALLOC"}, test_read}, - {{"FREAD", "FREAD WITH MALLOC"}, test_fread}, + {{"WRITE MOV ASM", "WRITE MOV ASM WITH MALLOC"}, + test_write_mov_all_bytes_asm}, + {{"WRITE NOP ASM", "WRITE NOP ASM WITH MALLOC"}, + test_write_nop_all_bytes_asm}, + {{"WRITE INC ASM", "WRITE INC ASM WITH MALLOC"}, + test_write_inc_all_bytes_asm}, + {{"WRITE DEC ASM", "WRITE DEC ASM WITH MALLOC"}, + test_write_dec_all_bytes_asm}, + // {{"READ", "READ WITH MALLOC"}, test_read}, + // {{"FREAD", "FREAD WITH MALLOC"}, test_fread}, }; tester.params.read_size = get_file_length(fp); @@ -155,6 +172,12 @@ void test_read(reptester *tester, alloc_type type) { fclose(fp); } +void write_to_all_bytes(char *buffer, u64 size) { + for (u64 i = 0; i < size; ++i) { + buffer[i] = i; + } +} + void test_write(reptester *tester, alloc_type type) { u64 start = read_cpu_timer(); u64 fault_count_start = page_fault_count(); @@ -163,9 +186,107 @@ void test_write(reptester *tester, alloc_type type) { u64 total_size = tester->params.read_size * tester->params.read_count; - for (u64 i = 0; i < total_size; ++i) { - tester->params.buffer[i] = '0'; - } + write_to_all_bytes(tester->params.buffer, total_size); + + u64 fault_count_end = page_fault_count(); + u64 end = read_cpu_timer(); + + u64 read_time = end - start; + u64 page_faults = fault_count_end - fault_count_start; + + tester->results = { + total_size, + read_time, + page_faults, + }; + + handle_free(tester, type); +} + +void test_write_mov_all_bytes_asm(reptester *tester, alloc_type type) { + u64 start = read_cpu_timer(); + u64 fault_count_start = page_fault_count(); + + handle_alloc(tester, type); + + u64 total_size = tester->params.read_size * tester->params.read_count; + + mov_all_bytes_asm(tester->params.buffer, total_size); + + u64 fault_count_end = page_fault_count(); + u64 end = read_cpu_timer(); + + u64 read_time = end - start; + u64 page_faults = fault_count_end - fault_count_start; + + tester->results = { + total_size, + read_time, + page_faults, + }; + + handle_free(tester, type); +} + +void test_write_nop_all_bytes_asm(reptester *tester, alloc_type type) { + u64 start = read_cpu_timer(); + u64 fault_count_start = page_fault_count(); + + handle_alloc(tester, type); + + u64 total_size = tester->params.read_size * tester->params.read_count; + + nop_all_bytes_asm(total_size); + + u64 fault_count_end = page_fault_count(); + u64 end = read_cpu_timer(); + + u64 read_time = end - start; + u64 page_faults = fault_count_end - fault_count_start; + + tester->results = { + total_size, + read_time, + page_faults, + }; + + handle_free(tester, type); +} + +void test_write_inc_all_bytes_asm(reptester *tester, alloc_type type) { + u64 start = read_cpu_timer(); + u64 fault_count_start = page_fault_count(); + + handle_alloc(tester, type); + + u64 total_size = tester->params.read_size * tester->params.read_count; + + inc_all_bytes_asm(total_size); + + u64 fault_count_end = page_fault_count(); + u64 end = read_cpu_timer(); + + u64 read_time = end - start; + u64 page_faults = fault_count_end - fault_count_start; + + tester->results = { + total_size, + read_time, + page_faults, + }; + + handle_free(tester, type); +} + +void test_write_dec_all_bytes_asm(reptester *tester, alloc_type type) { + u64 start = read_cpu_timer(); + u64 fault_count_start = page_fault_count(); + + handle_alloc(tester, type); + + u64 total_size = tester->params.read_size * tester->params.read_count; + + dec_all_bytes_asm(total_size); u64 fault_count_end = page_fault_count(); u64 end = read_cpu_timer(); diff --git a/haversine_02/src/repetition_testing/reptest_functions.asm b/haversine_02/src/repetition_testing/reptest_functions.asm new file mode 100644 index 0000000..f893d1a --- /dev/null +++ b/haversine_02/src/repetition_testing/reptest_functions.asm @@ -0,0 +1,43 @@ +global mov_all_bytes_asm +global nop_all_bytes_asm +global inc_all_bytes_asm +global dec_all_bytes_asm + +mov_all_bytes_asm: + xor rax, rax + + .loop: + mov BYTE [rdi + rax * 1], al + inc rax + cmp rsi, rax + jne .loop + + ret + +nop_all_bytes_asm: + xor rax, rax + + .loop: + db 0x0f, 0x1f, 0x00 + inc rax + cmp rdi, rax + jne .loop + + ret + +inc_all_bytes_asm: + xor rax, rax + + .loop: + inc rax + cmp rdi, rax + jne .loop + + ret + +dec_all_bytes_asm: + .loop: + dec rdi + jnz .loop + + ret