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