2016-09-12 2 views
0

Pouvez-vous me dire comment utiliser les instructions clflush()? J'ai écrit le code simple suivant pour mesurer la différence entre un temps d'exécution de lire une variable du cache et après l'expulser du cache. Cependant, je n'ai pas trouvé de résultats concluants. Quelle est la bonne façon d'expulser un cache en utilisant clflush()?Problèmes avec 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

Copie possible de [Comment utiliser clflush?] (Http://stackoverflow.com/questions/39448276/how-to-use-clflush) – Olaf

Répondre

0

Il semble que votre temps de vidage soit dépassé par le reste du code. Aussi, comme écrit, votre non-flush exécute moins de lignes de code (pas de flush), ce qui rend les comparaisons "injustes".

Que diriez-vous quelque chose comme:

#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; 
} 

De cette façon, nous Flushing toujours quelque chose, mais d'un test affecte votre monde, et l'autre ne fonctionne pas. Il n'utilise pas non plus d'asm inline.

Construit avec -O3, cela me donne des temps comme 149 pour non-flush et 312 pour flush.