Sto cercando di implementare alcuni assembler inline (in Visual Studio 2012 codice C++) per sfruttare SSE. Voglio aggiungere 7 numeri per 1e9 volte, quindi li ho posizionati dalla RAM ai registri xmm0 a xmm6 della CPU. quando lo faccio con assembly inline in Visual Studio 2012 con questo codice:L'utilizzo del registro XMM0 e dei recuperi di memoria (codice C++) è due volte più veloce dell'ASM usando solo registri XMM - Perché?
il codice C++:
for(int i=0;i<count;i++)
resVal+=val1+val2+val3+val4+val5+val6+val7;
mio codice ASM:
int count=1000000000;
double resVal=0.0;
//placing values to register
__asm{
movsd xmm0,val1;placing var1 in xmm0 register
movsd xmm1,val2
movsd xmm2,val3
movsd xmm3,val4
movsd xmm4,val5
movsd xmm5,val6
movsd xmm6,val7
pxor xmm7,xmm7;//turns xmm7 to zero
}
for(int i=0;i<count;i++)
{
__asm
{
addsd xmm7,xmm0;//+=var1
addsd xmm7,xmm1;//+=var2
addsd xmm7,xmm2;
addsd xmm7,xmm3;
addsd xmm7,xmm4;
addsd xmm7,xmm5;
addsd xmm7,xmm6;//+=var7
}
}
__asm
{
movsd resVal,xmm7;//placing xmm7 into resVal
}
e questo è il dis assemblati codice C++ compilatore per il codice 'resVal + = val1 val2 + + + val3 val4 + val5 + Val6 + val7':
movsd xmm0,mmword ptr [val1]
addsd xmm0,mmword ptr [val2]
addsd xmm0,mmword ptr [val3]
addsd xmm0,mmword ptr [val4]
addsd xmm0,mmword ptr [val5]
addsd xmm0,mmword ptr [val6]
addsd xmm0,mmword ptr [val7]
addsd xmm0,mmword ptr [resVal]
movsd mmword ptr [resVal],xmm0
Come è visibile la cOMPI usa un solo registro xmm0 e per altre volte sta recuperando i valori dalla RAM.
La risposta di entrambi i codici (il mio codice ASM e il codice C++) è la stessa ma il codice C++ impiega circa la metà del tempo del mio codice asm da eseguire!
Mi è stato letto sui registri della CPU che lavorare con loro è molto più veloce della memoria. Non penso che questo rapporto sia vero. Perché la versione asm ha prestazioni inferiori del codice C++?
Perché stai facendo questo? È strettamente un esercizio di apprendimento o hai qualcosa che vuoi raggiungere? –
@Bwmat: il compilatore ottiene il valore dalla RAM ogni volta e lo fa per 1e9 volte, ma potrebbe essere un vantaggio posizionare valori nei registri della CPU e ottenerli per 1e9 volte! – epsi1on
Sono leggermente sorpreso che il compilatore non abbia ottimizzato l'intero 'val1 + val2 + val3 + val4 + val5 + val6 + val7' e lo sostituisca con un singolo valore. – Mysticial