Il compilatore non incorpora nulla?

3

Ho lanciato la mia libreria matematica accelerata SIMD . È diventato abbastanza completo, così naturalmente sono andato a condurre test di velocità e ottimizzarlo.

Btw non è un'ottimizzazione prematura, la lib in realtà è completa di funzionalità, ho davvero bisogno che sia veloce ora.

Ad ogni modo, sto testando alcuni metodi di prodotti con puntini vettoriali contro quelli di DirectXMath di Microsoft. La differenza tra i miei vettori e quelli in DirectXMath è che in DirectXMath XMVECTOR è solo un __m128 nudo, mentre il mio è un __m128 all'interno di una classe vector_simd che è allineata a 16 byte e con un allocatore allineato.

Ora si ipotizzerebbe che con tutte le ottimizzazioni possibili abilitate in modalità di rilascio si compilerebbero alla stessa cosa. Voglio dire int a; e int arr[1]; compili alla stessa cosa in modalità rilascio, proprio come la mia classe template array ha le stesse prestazioni di una matrice raw e così via ... ma con mia sorpresa i metodi della mia classe sono arrivati 2 volte più lento. Ho persino provato a incollare il codice SSE da DirectXMath nel metodo della mia classe, ma è uscito ancora più lentamente. Quindi l'unica cosa rimasta era la differenza che uno è una classe e l'altro è grezzo.

Sembrava da un po 'che il sovraccarico di accedervi come membro della classe e / o il sovraccarico extra del costruttore (che è vuoto ...). Comunque ho messo tutte le definizioni dei miei metodi di classe vector nella sua intestazione e ancora è risultato 2x più lento di DirectXMath.

Forse il sovraccarico deriva dal fatto che __m128 è un membro della classe?

Non capisco perché il compilatore non possa ottimizzarlo, è come avere una struttura con un singolo intero in esso? Qualcun altro ha avuto problemi di questo tipo?

EDIT: OK, quindi sembra che la mia classe vector_simd sia 32 byte, mentre __m128 è solo 16 byte, il che è strano. Quando ho rimosso l'allineamento a 16 byte dalla mia classe, è diventato anche 16 byte di grandi dimensioni. Ma questo non ha senso, l'allineamento di una classe da 16 byte a 16 byte dovrebbe farlo rimanere 16 byte ....

    
posta ulak blade 17.11.2013 - 20:36
fonte

1 risposta

1

Scoprire perché il codice è più lento può essere eccezionalmente difficile, ma per una differenza grossolana come un raddoppiamento del tempo di esecuzione, puoi avere una buona idea di almeno dove iniziare guardando usando un profiler . È necessario essere particolarmente consapevoli di dove i dati vengono copiati, specialmente all'interno di un ciclo; che può facilmente diventare costoso. (Suggerisco uno strumento come cachegrind, ma non so se è disponibile per la tua piattaforma.)

I problemi di allineamento sono in realtà più facili da individuare e correggere. In particolare, se hai una struttura come questa:

struct {
   eightByteQuantity a;
   eightByteQuantity b;
};

Impostando il suo allineamento a 16 byte si forza facilmente l'allineamento di ciascun membro su un limite di 16 byte, raddoppiando la dimensione effettiva. Tieni presente che anche le dimensioni di cose come puntatori vtable devono essere pagate.

    
risposta data 18.11.2013 - 01:44
fonte

Leggi altre domande sui tag