Last active
January 5, 2017 13:19
-
-
Save run4flat/fcbb6480275b1b9dcaa7a8d3a8084638 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* See if I can trigger the cache trashing issue. | |
* | |
* Use tcc to compile and run with: | |
* ./tcc -B. -DNOPS=0 -run cache-test-simple.c | |
* | |
* For performance metrics, try | |
* perf stat -d -d -d ./tcc -B. -DNOPS=0 -run cache-test-simple.c | |
*/ | |
#include <stdio.h> | |
int foo; | |
void spin_wheels() { | |
foo = 0; | |
if (foo) { | |
#if NOPS >= 1 | |
foo++; | |
#endif | |
#if NOPS >= 2 | |
foo++; | |
#endif | |
#if NOPS >= 3 | |
foo++; | |
#endif | |
#if NOPS >= 4 | |
foo++; | |
#endif | |
#if NOPS >= 5 | |
foo++; | |
#endif | |
#if NOPS >= 6 | |
foo++; | |
#endif | |
#if NOPS >= 7 | |
foo++; | |
#endif | |
#if NOPS >= 8 | |
foo++; | |
#endif | |
#if NOPS >= 9 | |
foo++; | |
#endif | |
#if NOPS >= 10 | |
foo++; | |
#endif | |
#if NOPS >= 11 | |
foo++; | |
#endif | |
#if NOPS >= 12 | |
foo++; | |
#endif | |
#if NOPS >= 13 | |
foo++; | |
#endif | |
#if NOPS >= 14 | |
foo++; | |
#endif | |
#if NOPS >= 15 | |
foo++; | |
#endif | |
#if NOPS >= 16 | |
foo++; | |
#endif | |
} | |
foo++; | |
} | |
#include <stdio.h> | |
int main(int argc, char **argv) | |
{ | |
/* perform the requested number of iterations */ | |
for (int i = 0; i < 10000000; i++) spin_wheels(); | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* See if I can trigger the cache trashing issue. | |
* | |
* Compile with | |
* gcc cache-test.c -L. -ltcc -ldl -o cache-test | |
* | |
* Run as | |
* ./cache-test mem 30 50000000 | |
* or, for performance metrics, try | |
* perf stat -d -d -d ./cache-test mem 30 50000000 | |
*/ | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include "libtcc.h" | |
void setup_paths(TCCState * state, char **argv); | |
int setup_link_process(TCCState * state, char **argv); | |
char * generate_library_code(int N_commands); | |
void make_library(TCCState * state, int link_process, char *code_to_emit); | |
void * get_wheels_ptr(TCCState * state, int link_process); | |
int main(int argc, char **argv) | |
{ | |
/* Print usage error statement */ | |
if (argc != 4) { | |
printf("Usage: %s <mem|so> <N-commands> <N-iterations>\n", | |
argv[0]); | |
return 1; | |
} | |
/* Set up compiler for 'library' code */ | |
TCCState *s = tcc_new(); | |
setup_paths(s, argv); | |
int link_process = setup_link_process(s, argv); | |
/* Assemble library code */ | |
int N_commands = atoi(argv[2]); | |
char * code_to_compile = generate_library_code(N_commands); | |
//printf("code to compile:\n%s\n", code_to_compile); | |
make_library(s, link_process, code_to_compile); | |
void (*spin_wheels)() = get_wheels_ptr(s, link_process); | |
/* perform the requested number of iterations */ | |
int i, N_iterations = atoi(argv[3]); | |
for (i = 0; i < N_iterations; i++) spin_wheels(); | |
return 0; | |
} | |
/* use the current directory as the lib path so this will work with | |
* whatever is being built at the moment. */ | |
void setup_paths(TCCState * state, char **argv) { | |
tcc_set_lib_path(state, "."); | |
} | |
int setup_link_process(TCCState * state, char **argv) { | |
int output_type = TCC_OUTPUT_MEMORY; | |
if (strcmp(argv[1], "so") == 0) output_type = TCC_OUTPUT_DLL; | |
else if (strcmp(argv[1], "mem") != 0) { | |
printf("Invalid output type '%s'\n", argv[1]); | |
printf("Usage: %s <mem|so> <N-commands> <N-iterations>\n", | |
argv[0]); | |
exit(1); | |
} | |
tcc_set_output_type(state, output_type); | |
return output_type; | |
} | |
/* produces a function for the library with the specified number of | |
* commands in the body of the function. */ | |
char header[] = "int i; void spin_wheels() {i = 0; if (i) {"; | |
char footer[] = "} i++; }"; | |
char * ops[] = { | |
"i++;", | |
"i--;", | |
}; | |
#define OP_LENGTH 4 | |
char * generate_library_code(int N_commands) { | |
/* compute length and allocate */ | |
int total_length = sizeof(header) + N_commands * OP_LENGTH | |
+ sizeof(footer) - 1; | |
char * to_return = malloc(total_length); | |
char * curr_offset = to_return + sizeof(header) - 1; | |
/* set header */ | |
strcpy(to_return, header); | |
/* assemble operations */ | |
for (int i = 0; i < N_commands; i++) { | |
strcpy(curr_offset, ops[i % 2]); | |
curr_offset += OP_LENGTH; | |
} | |
/* closing bracket and trailing null */ | |
strcpy(curr_offset, footer); | |
curr_offset[sizeof(footer)] = '\0'; | |
return to_return; | |
} | |
void make_library(TCCState * state, int link_process, char *code_to_compile) { | |
tcc_compile_string(state, code_to_compile); | |
if (link_process == TCC_OUTPUT_MEMORY) { | |
printf("Code bytes: %d\n", tcc_relocate(state, 0)); | |
tcc_relocate(state, TCC_RELOCATE_AUTO); | |
} | |
else { | |
tcc_output_file(state, "cache-test.so"); | |
} | |
} | |
#include <dlfcn.h> | |
void * get_wheels_ptr(TCCState * state, int link_process) { | |
if (link_process == TCC_OUTPUT_MEMORY) { | |
return tcc_get_symbol(state, "spin_wheels"); | |
} | |
void * lib = dlopen("./cache-test.so", RTLD_NOW); | |
return dlsym(lib, "spin_wheels"); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment