2014-04-04 14 views
5

leggevo this on MSDN, e si dicePerché non dovresti accedere direttamente ai campi __m128i?

non si deve accedere direttamente ai campi __m128i. Tuttavia, è possibile vedere questi tipi nel debugger. Una variabile di tipo __m128i si associa ai registri XMM [0-7].

Tuttavia, non spiega perché. Perché è? Per esempio, è il seguente "cattivo":

void func(unsigned short x, unsigned short y) 
{ 
    __m128i a; 
    a.m128i_i64[0] = x; 

    __m128i b; 
    b.m128i_i64[0] = y; 

    // Now do something with a and b ... 
} 

Invece di fare le assegnazioni, come nell'esempio di cui sopra, si dovrebbe utilizzare una sorta di load funzione?

+2

I campi sono specifiche di Microsoft. Ovviamente a loro non interessa, dato che adoreranno bloccarti nel loro compilatore. La vera ragione è per le prestazioni. Non esiste un modo efficace per accedere ai singoli elementi di un registro SSE. SSE4.1 ha istruzioni per farlo, ma l'indice deve essere una costante in fase di compilazione. – Mysticial

risposta

6

Il campo m128i_i64 e la famiglia sono Microsoft estensioni specifiche del compilatore. Non esistono nella maggior parte degli altri compilatori.

Tuttavia, essi sono utili a scopo di test.


La vera ragione per evitare il loro uso è prestazioni. L'hardware non può accedere in modo efficiente ai singoli elementi di un vettore SIMD.

  • Non ci sono istruzioni che consentono di accedere direttamente ai singoli elementi. (SSE4.1 fa, ma richiede un indice costante fase di compilazione.)
  • Percorrendo memoria eventualmente a un grande rigore, a causa dell'incapacità store forwarding.

AVX e AVX2 non estendono le istruzioni SSE4.1 per consentire l'accesso agli elementi in un vettore a 256 bit. E per quanto posso dire, AVX512 non lo avrà per i vettori a 512 bit.

Analogamente, gli intrinseci fissato (come _mm256_set_pd()) subiscono lo stesso problema. Sono implementati sia come una serie di operazioni di mescolamento dei dati. Oppure passando attraverso la memoria e assumendo le bancarelle del negozio.


che pone la domanda: C'è un modo efficiente per popolare un vettore SIMD dai componenti scalari? (O separare un vettore SIMD in componenti scalari)

Risposta breve: Non proprio. Quando si utilizza SIMD, ci si aspetta che faccia molto del lavoro nel modulo vettoriale. Quindi l'overhead di inizializzazione non dovrebbe avere importanza.

+0

È bello vedere di nuovo una risposta da parte tua su Mystical su SIMD. Il link wiki sull'inoltro negozio è interessante. –

+0

Sì. L'inoltro dei negozi è un grosso problema per i processori moderni. Senza di esso si pagano penali di oltre 20 cicli per la lettura dopo la scrittura. Sfortunatamente, tende a fallire quando si tenta di leggere la memoria usando una dimensione diversa in cui è stato scritto. I processori più recenti sono migliori in quanto è possibile leggere finché è completamente contenuto in una scrittura in sospeso. Ma impostare l'intrinseca va dall'altra parte. E le unità di negozio non sono attualmente in grado di coalizzare i negozi più piccoli in uno grande in modo che possa essere inoltrato a un carico più grande. – Mysticial

+0

Grazie!Quindi nel mio esempio di codice, come si dovrebbero caricare gli argomenti nei tipi __m128i? Da alcune altre domande, posso vedere come farlo con gli array. Tuttavia, caricare solo un numero intero semplice mi dà una violazione di accesso. Questo è probabilmente un problema di allineamento, ma non sono sicuro di come risolverlo in un modo non specifico MS ... – Gideon

Problemi correlati