I'm experimenting with cache flush and then reload but something is not normal

68 Views Asked by At

This is my code. Normally, the reload time after I refresh the cache will be a little above the threshold, but sometimes it will be lower than the threshold. Why?


#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <sched.h>
#include <immintrin.h>
#include <emmintrin.h>
#include <mmintrin.h>
#define CALIB_TRY 100000

/*memaccesstime fucntion*/
uint32_t memaccesstime(void *v) {
  uint32_t rv;
  asm volatile (
      "mfence\n"
      "lfence\n"
      "rdtscp\n"
      "mov %%eax, %%esi\n"
      "mov (%1), %%eax\n"
      "rdtscp\n"
      "sub %%esi, %%eax\n"
      : "=&a" (rv): "r" (v): "ecx", "edx", "esi");
  return rv;
}

/*flush function*/
void flush(void *v) {
  asm volatile ("clflush 0(%0)": : "r" (v):);
}

/*memory access function*/
void memaccess(void *v) {
  asm volatile("movq (%0), %%rax\n" : : "r"(v) : "rax");
}


/*compute the threshold*/
size_t fr_probethreshold (void) {
  static char dummy;
  size_t res_a = 0;
  size_t res_n = 0;
  for (int i = 0; i < CALIB_TRY; i++) {
    _mm_clflush(&dummy);
    res_a += memaccesstime(&dummy);
  }
  for (int i = 0; i < CALIB_TRY; i++) {
    res_n += memaccesstime(&dummy);
  }
  res_a /= CALIB_TRY;
  res_n /= CALIB_TRY;
  printf("avg access time: %ld, avg no access time: %ld\n", res_a, res_n);
  return (res_a + res_n*2) / 3;
}

/* reload time function*/
int64_t reload(void *addr) {
  int64_t start = _rdtsc();
  memaccess(addr);
  return _rdtsc() - start;
}

int main(){

size_t threshold= fr_probethreshold();
printf("The threshold computed by this function is : %ld \n", threshold);
void * ptr;


int num[5] ={1,2,3,4,5};
ptr = &num[3];

int normal=0;
int unormal=0;
int k=10000;

while(1){
/*after flush*/
flush(ptr);
int64_t time2 = memaccesstime(ptr);
printf("the time should longer than threshold\n");
printf("the time after flush is %ld\n",time2);
if(time2 > threshold){
normal++;
}else{
unormal++;
}
k--;
if(k==0){break;}
//flush(ptr);
}

printf("the normal is %d\n",normal);
printf("the unormal is %d\n",unormal);
}

Whe result is like this: enter image description here

An anomaly appears in the results

0

There are 0 best solutions below