From 4dd1918a8ca6b48cc8cf13716e15b87306fbdf32 Mon Sep 17 00:00:00 2001 From: yves Date: Wed, 25 May 2011 09:52:21 +0200 Subject: yeah --- cacheRows.c | 37 ++++++++++++++++++++++++++++++------- cacheSize.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ handy_cmdlines | 7 +++++++ inlineasm.h | 27 +++++++++++++++++---------- 4 files changed, 109 insertions(+), 17 deletions(-) create mode 100644 cacheSize.c create mode 100644 handy_cmdlines diff --git a/cacheRows.c b/cacheRows.c index 0111018..6791257 100644 --- a/cacheRows.c +++ b/cacheRows.c @@ -2,15 +2,28 @@ #include "inlineasm.h" #include -#define MEASURE_METHOD memmeasure +#define MEASURE_METHOD doMeasure +#define RUNS 10000 #define MIN_OFFSET 1 -#define MAX_OFFSET 4096 +#define MAX_OFFSET 128 #define OFFSETS (MAX_OFFSET - MIN_OFFSET) #define FIELD_TYPE uint8_t +uint64_t doMeasure(FIELD_TYPE *addr){ + uint64_t volatile time = 0; + + FIELD_TYPE value = (FIELD_TYPE) &addr; + + time = rdtsc(); + *addr = value; + time = rdtsc() - time; + + return time; +} + void measure(int offset,FIELD_TYPE *field){ - uint64_t *res = malloc(sizeof(uint64_t)*MAX_OFFSET); - void *lowerAddress = field + offset; + FIELD_TYPE *lowerAddress = field + offset; + *lowerAddress = 0; int i; int a = field[0]; @@ -18,20 +31,30 @@ void measure(int offset,FIELD_TYPE *field){ res[i] = MEASURE_METHOD(lowerAddress,res[i]*sizeof(FIELD_TYPE)); } - for(i=MIN_OFFSET;i <= MAX_OFFSET;i++){ - fprintf(stdout,"%d %lld \r\n",i,res[i]); + for(i=MIN_OFFSET;i <= MAX_OFFSET;i += 8){ + uint64_t time = MEASURE_METHOD(lowerAddress+i); + if(time > 70) + fprintf(stdout,"%d %ld \r\n",i,time); } } + + int main(int argc, char* argv[]) { //uint64_t *results = malloc(sizeof(uint64_t)*RUNS*OFFSETS); FIELD_TYPE *field = malloc(sizeof(FIELD_TYPE)*(MAX_OFFSET+1)); + + int i=0; - measure(0,field); + //for(i=0;i < RUNS;i++){ + //fprintf(stdout,"RUN: %d \r\n",i); + //} + measure(0,field); + return 0; } diff --git a/cacheSize.c b/cacheSize.c new file mode 100644 index 0000000..2949df9 --- /dev/null +++ b/cacheSize.c @@ -0,0 +1,55 @@ +#include +#include "inlineasm.h" +#include + +#define MEASURE_METHOD doMeasure +#define RUNS 10000 +#define MIN_OFFSET 1 +#define MAX_OFFSET (32*4069) +#define OFFSETS (MAX_OFFSET - MIN_OFFSET) +#define FIELD_TYPE uint8_t + +uint64_t doMeasure(FIELD_TYPE *addr){ + uint64_t volatile time = 0; + + FIELD_TYPE value = (FIELD_TYPE) &addr; + + time = rdtsc(); + *addr = value; + time = rdtsc() - time; + + return time; +} + +void measure(int offset,FIELD_TYPE *field){ + FIELD_TYPE *lowerAddress = field + offset; + *lowerAddress = 0; + int i; + + for(i=MIN_OFFSET;i <= MAX_OFFSET;i += 32){ + uint64_t time = MEASURE_METHOD(lowerAddress+i); + if(time > 500) + fprintf(stdout,"%d %ld \r\n",i,time); + } +} + + + +int main(int argc, char* argv[]) { + + //uint64_t *results = malloc(sizeof(uint64_t)*RUNS*OFFSETS); + FIELD_TYPE *field = malloc(sizeof(FIELD_TYPE)*(MAX_OFFSET+1)); + + + int i=0; + + //for(i=0;i < RUNS;i++){ + //fprintf(stdout,"RUN: %d \r\n",i); + //} + + + measure(0,field); + + return 0; +} + diff --git a/handy_cmdlines b/handy_cmdlines new file mode 100644 index 0000000..05b6874 --- /dev/null +++ b/handy_cmdlines @@ -0,0 +1,7 @@ +for i in $(seq 1 1000) ; do ./test ; done | sort | uniq -c | awk '{ sum += ($1 * $2) } END { print sum }' +for i in $(seq 1 1000) ; do ./test ; done | awk '{ sum += $1 ; counter+=1 ; print sum/counter }' + +gcc cacheRows.c -O0 && ./a.out w> output && Rscript plot.r + +gcc cacheRows2.c -o cacheRows2 ; mkdir -p out ; for i in $(seq -w 1 10) ; do ./cacheRows2 10000 40 1000 output.dat ; Rscript plot2.r ; mv output.png out/$i.png ; mv output.dat out/$i.dat ; done +gcc cacheRows2.c -o cacheRows2 ; echo "Offset Ticks" > output.dat ; for i in $(seq 1 100) ; do ./cacheRows2 10000 40 1000 - >> output.dat ; echo RUN $i done ; done ; echo 'Done ... now generating graph (this may take a while)' ; Rscript plot2.r diff --git a/inlineasm.h b/inlineasm.h index 218c532..6e33660 100644 --- a/inlineasm.h +++ b/inlineasm.h @@ -63,21 +63,28 @@ static uint64_t memmeasure(char* memory, uint64_t offset) // rdtsc to save instrucions. it is not significantly faster than the // accurate one but it has fewer instrucions and by that is less likely // to be delayed by the scheduler -// averages at about 72.5 ticks with an offset of 1 -static uint64_t optmemmeasure(char* memory, uint64_t offset) +static uint64_t optmemmeasure(char* memoryFirst, char* memorySecond) { - asm( + asm volatile ( + // load other value + "mov (%%rbx), %%rax ;" + + // start clock measure "rdtsc ;" "mov %%eax, %%edi ;" - - // here be magic dragons and memory access (read segfaults) ahead - // TODO: evaluate if more cmp types (like w and l) do make sense - "cmpb $0x23, (%%rbx) ;" - "cmpb $0x42, (%%rbx,%%rcx) ;" - + + // load second value + "mov (%%rcx), %%rdx ;" + + // stop clock measure "rdtsc ;" "sub %%edi, %%eax ;" - : : "b" (memory), "c" (offset) + + // do shit + "xor (%%rax,%%rdx), %%rbx ;" + "mov %%rbx, (%%rcx) ;" + + : : "b" (memoryFirst), "c" (memorySecond) ); } -- cgit v1.2.3-1-g7c22