2016-09-12 8 views
0

clflush() 지침을 사용하는 방법을 알려주시겠습니까? 필자는 다음과 같은 간단한 코드를 작성하여 캐시에서 변수를 읽는 시간과 캐시에서 변수를 읽은 시간 간의 차이를 측정했습니다. 그러나 나는 결정적인 결과를 찾지 못했습니다. 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; 
      } 
+1

[clflush 사용 방법]의 가능한 복제본 (http://stackoverflow.com/questions/39448276/how-to-use-clflush) – Olaf

답변

0

'플러시'시간이 나머지 코드에 의해 압도되고있는 것처럼 보입니다. 또한 작성된대로 비 플러시 (non-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와 같은 시간을 얻을 수 있습니다.