你能告诉我如何使用clflush()指令吗?我编写了以下简单的代码来测量从缓存读取变量的执行时间与从缓存中逐出变量后的执行时间之间的差异。不过,我没有找到确切的结果。使用clflush()逐出缓存的正确方法是什么?
#include <stdio.h>
#include <stdint.h>
#include"cpucycles.c"
#define REPEAT 1900000
inline void clflush(volatile void *p)
{
asm volatile ("clflush (%0)" :: "r"(p));
}
inline uint64_t rdtsc()
{
unsigned long a, d;
asm volatile ("cpuid; rdtsc" : "=a" (a), "=d" (d) : : "ebx", "ecx");
return a | ((uint64_t)d << 32);
}
volatile int i;
inline void test()
{
uint64_t start, end,clock;
volatile int j;
long int rep;
int k;
clock=0;
for(rep=0;rep<REPEAT;rep++){
start = rdtsc();
j = i+1;
end = rdtsc();
clock=clock+(end-start);
k=j;
}
printf("took %lu ticks\n", clock);
}
inline void testflush()
{
uint64_t start, end,clock;
volatile int j;
int k;
long int rep;
clock=0;
for(rep=0;rep<REPEAT;rep++){
start = rdtsc();
j = i+1;
end = rdtsc();
clflush(&i);
clock=clock+(end-start);
k=j;
}
printf("took %lu ticks\n", clock);
}
int main(int ac, char **av)
{
i=5;
printf("------------------------------------------\n");
test();
printf("------------------------------------------\n");
testflush();
printf("------------------------------------------\n");
test();
return 0;
}
最佳答案
看起来你的“冲水”时间被剩下的代码淹没了。而且,正如所写的,非flush执行的代码行更少(非flush),这使得比较“不公平”
再来点像这样的吧:
#include <stdio.h>
#include <stdint.h>
#include <malloc.h>
#include <emmintrin.h>
#define REPEAT 1900000
volatile int i;
inline void test(void *v)
{
uint64_t start, end;
volatile int j;
long int rep;
int k;
start = __builtin_ia32_rdtsc();
for(rep=0;rep<REPEAT;rep++){
j = i+1;
_mm_clflush(v);
k=j;
}
end = __builtin_ia32_rdtsc();
printf("%p took %lu ticks\n", v, end-start);
}
int main(int ac, char **av)
{
void *v = malloc(1000);
i=5;
printf("------------------------------------------\n");
test(v);
printf("------------------------------------------\n");
test((void *)&i);
printf("------------------------------------------\n");
test(v);
free(v);
return 0;
}
这样我们总是刷新一些东西,但是一个测试影响全局,而另一个不影响全局。它也不使用任何内联asm。
使用-O3构建,这给了我149倍的非冲洗时间和312倍的冲洗时间。