Spettro PoC - Basato su carta - risultati opposti

0

Dopo una lunga discussione con questa domanda (Grazie per l'aiuto!)

Spectre Proof of Concept (PoC) Esecuzione speculativa: verifica del valore

È arrivato con un semplice PoC basato su Spectre paper.

Sembra coerente, provato anche con altri personaggi e ottenuto risultati simili.

Esecuzione:

user@laptop:~/labspectre$ ./spectre7
Z should be cached
trying: E time: 96
trying: X time: 93
trying: W time: 93
trying: F time: 93
trying: O time: 93
trying: J time: 93
trying: C time: 93
trying: K time: 93
trying: Y time: 93
trying: T time: 93
trying: D time: 93
trying: M time: 93
trying: L time: 93
trying: P time: 93
trying: Q time: 93
trying: A time: 93
trying: B time: 93
trying: V time: 93
trying: N time: 93
trying: I time: 93
trying: U time: 93
trying: S time: 93
trying: H time: 93
trying: G time: 93
trying: Z time: 8152
trying: R time: 93
user@laptop:~/labspectre$ ./spectre7
Z should be cached
trying: R time: 96
trying: X time: 92
trying: F time: 93
trying: O time: 93
trying: C time: 93
trying: P time: 93
trying: W time: 93
trying: U time: 93
trying: H time: 93
trying: T time: 93
trying: G time: 93
trying: Z time: 259
trying: K time: 93
trying: V time: 93
trying: J time: 93
trying: D time: 96
trying: M time: 93
trying: Q time: 93
trying: L time: 93
trying: E time: 93
trying: B time: 93
trying: S time: 93
trying: A time: 93
trying: Y time: 93
trying: N time: 93
trying: I time: 93
user@laptop:~/labspectre$ ./spectre7
Z should be cached
trying: S time: 97
trying: W time: 93
trying: C time: 93
trying: V time: 93
trying: K time: 93
trying: P time: 93
trying: T time: 93
trying: Y time: 93
trying: A time: 93
trying: U time: 93
trying: N time: 93
trying: D time: 93
trying: O time: 93
trying: J time: 93
trying: R time: 93
trying: M time: 93
trying: F time: 93
trying: Q time: 93
trying: G time: 93
trying: H time: 93
trying: I time: 93
trying: E time: 93
trying: B time: 93
trying: Z time: 230
trying: L time: 93
trying: X time: 93
user@laptop:~/labspectre$ ./spectre7
Z should be cached
trying: B time: 97
trying: A time: 93
trying: P time: 93
trying: I time: 93
trying: M time: 93
trying: E time: 93
trying: W time: 93
trying: H time: 93
trying: V time: 93
trying: D time: 93
trying: N time: 93
trying: Y time: 93
trying: T time: 93
trying: K time: 93
trying: J time: 93
trying: X time: 93
trying: R time: 93
trying: S time: 93
trying: L time: 93
trying: U time: 93
trying: G time: 93
trying: C time: 93
trying: Z time: 328
trying: O time: 93
trying: Q time: 93
trying: F time: 93
user@laptop:~/labspectre$ ./spectre7
Z should be cached
trying: B time: 97
trying: G time: 93
trying: O time: 93
trying: X time: 93
trying: N time: 93
trying: F time: 93
trying: A time: 93
trying: Q time: 93
trying: Y time: 93
trying: M time: 93
trying: S time: 93
trying: K time: 93
trying: I time: 93
trying: W time: 93
trying: J time: 93
trying: R time: 93
trying: C time: 93
trying: V time: 93
trying: L time: 93
trying: Z time: 272
trying: P time: 93
trying: U time: 93
trying: H time: 92
trying: T time: 93
trying: E time: 93
trying: D time: 93
user@laptop:~/labspectre$ ./spectre7
Z should be cached
trying: R time: 97
trying: A time: 95
trying: M time: 153
trying: F time: 95
trying: H time: 93
trying: L time: 93
trying: D time: 92
trying: G time: 93
trying: K time: 93
trying: U time: 93
trying: S time: 93
trying: W time: 93
trying: O time: 97
trying: Y time: 93
trying: Z time: 289
trying: C time: 93
trying: P time: 93
trying: Q time: 100
trying: B time: 92
trying: J time: 92
trying: I time: 92
trying: V time: 95
trying: E time: 93
trying: X time: 93
trying: T time: 93
trying: N time: 93
user@laptop:~/labspectre$ ./spectre7
Z should be cached
trying: P time: 98
trying: I time: 93
trying: F time: 93
trying: L time: 93
trying: W time: 93
trying: D time: 93
trying: V time: 93
trying: S time: 93
trying: H time: 93
trying: J time: 93
trying: K time: 93
trying: M time: 93
trying: O time: 93
trying: A time: 93
trying: Z time: 363
trying: X time: 93
trying: C time: 93
trying: Y time: 93
trying: E time: 93
trying: Q time: 93
trying: B time: 93
trying: R time: 93
trying: N time: 93
trying: T time: 93
trying: U time: 93
trying: G time: 93

Sample Spect PoC

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#ifdef _MSC_VER
#include <intrin.h> /* for rdtscp and clflush */
#pragma optimize("gt",on)
#else
#include <x86intrin.h> /* for rdtscp and clflush */
#endif




void main(void)
{
volatile uint8_t array1[26] = { 65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90 };

uint8_t array2[256 * 512];

for(int i = 0; i < sizeof(array2); i++)
  array2[i] = 1; /* write to array2 so in RAM not copy-on-write zero pages */


for(int i = 0; i < 256; i++)
  _mm_clflush(&array2[i * 512]); /* intrinsic for clflush instruction */



printf("%c should be cached\n", array1[25]);

int dummy = 0;
for(int i=0; i<26; i++) {
 if (i != 25) {
    array2[array1[i] * 512] = array1[i]; 
 }
}



int t0,time_taken = 0;
int junk = 0;

int mix_i=0;

 int i,j;
    int aux,res;

    char RandomId[26];
    char ListId[26]={65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90};



    srand(time(NULL));

    for(i=0; i<26; i++)
    {
        res = rand() % 26;
        aux = ListId[res];

        if (ListId[res] != -1)
        {
            RandomId[i] = aux;
            ListId[res] = -1;
        }
        else
            i--;
    }



volatile uint8_t * addr;
int y=0;


  for(int i=0; i<26; i++)
  {
    mix_i = RandomId[i];
    addr = &array2[mix_i * 512];
    t0 = __rdtscp(&junk); 
    junk = *addr;
    time_taken = __rdtscp(&junk) - t0;
    if(mix_i>=65 && mix_i<=90)
    printf("trying: %c time: %i\n",mix_i,time_taken);
  }
}

La mia grande domanda è tuttavia:

Cosa c'è di sbagliato in questo? Dov'è il mio errore?

Dato che mostra i tempi di accesso HIGHER per i valori memorizzati nella cache (caricati speculativamente)?

Sto utilizzando il processore AMD A10-5757M.

    
posta android_dev 18.01.2018 - 09:56
fonte

1 risposta

1

Svuota la matrice dalla cache qui -

for(int i = 0; i < 256; i++)
  _mm_clflush(&array2[i * 512]); /* intrinsic for clflush instruction */

Quindi lo rimetti nella cache

for(int i=0; i<26; i++) {
  if (i != 25) {
    array2[array1[i] * 512] = array1[i]; 
  }
}

Questo suggerisce per i == 25 il ramo if non preso (cioè non eseguito speculativamente). Ogni altra pagina dell'array viene memorizzata nella cache, ma la pagina a cui fa riferimento "Z" non lo è.

Come ho detto nella tua domanda precedente hai davvero bisogno di capire come funziona la dimostrazione del concetto che stai tentando di replicare prima di arrivare da qualsiasi parte.

Per quanto riguarda il motivo per cui non esiste un'esecuzione speculativa ci sono un certo numero di possibilità. Ad esempio, non hai tentato di addestrare pesantemente il ramo. È anche possibile che il compilatore o il processore stiano ottimizzando il! = 25 e riducendo l'istruzione "i < 26".

    
risposta data 18.01.2018 - 10:06
fonte

Leggi altre domande sui tag