Ho giocato con l'assembler inline e SSE di D's, ma ho trovato qualcosa che non capisco. Quando provo ad aggiungere due vettori float4 immediatamente dopo la dichiarazione, il calcolo è corretto. Se inserisco il calcolo in una funzione separata, ottengo una serie di nan
s.SSE stranezza con funzioni
//function contents identical to code section in unittest
float4 add(float4 lhs, float4 rhs)
{
float4 res;
auto lhs_addr = &lhs;
auto rhs_addr = &rhs;
asm
{
mov RAX, lhs_addr;
mov RBX, rhs_addr;
movups XMM0, [RAX];
movups XMM1, [RBX];
addps XMM0, XMM1;
movups res, XMM0;
}
return res;
}
unittest
{
float4 lhs = {1, 2, 3, 4};
float4 rhs = {4, 3, 2, 1};
println(add(lhs, rhs)); //float4(nan, nan, nan, nan)
//identical code starts here
float4 res;
auto lhs_addr = &lhs;
auto rhs_addr = &rhs;
asm
{
mov RAX, lhs_addr;
mov RBX, rhs_addr;
movups XMM0, [RAX];
movups XMM1, [RBX];
addps XMM0, XMM1;
movups res, XMM0;
} //end identical code
println(res); //float4(5, 5, 5, 5)
}
Il complesso è funzionalmente identica (per quanto posso dire) a this link.
Modifica: sto usando una struttura personalizzata float4 (per ora, è solo un array) perché voglio essere in grado di avere una funzione di aggiunta come float4 add(float4 lhs, float rhs)
. Per il momento, che si traduce in un errore di compilazione come questo:
Error: floating point constant expression expected instead of rhs
Nota: sto usando DMD 2.071.0
Spero che non stiate progettando di utilizzare effettivamente un codice del genere per le prestazioni. Stai costringendo il compilatore a memorizzare i vettori in memoria e quindi memorizzarli in memoria. Quindi stai scrivendo il codice che carica gli indirizzi dalla memoria e ricarica i vettori. (Nell'ABI 'vectorcall' di Windows, e nell'ABI SysV utilizzato da tutti gli altri sistemi AMD64, gli argomenti vettoriali sono passati nei registri vettoriali). In D, IDK se 'lhs_addr' può effettivamente essere un registro, ma è comunque una mossa reg-reg inutile al meglio. Idealmente c'è una sintassi per chiedere i vettori in regs specifici, come GNU C inline asm. –
Sto provando a scrivere il mio tipo float4 perché 'float4 rhs_vec = [rhs, rhs, rhs, rhs];' non è consentito con l'errore nella domanda. Al momento ho essenzialmente copiato il codice dal link, e ho apportato qualche piccola modifica (si spera) a farlo funzionare in D. Al momento, deve solo funzionare. Tuttavia, cosa faresti invece per la sezione? Questa è solo la mia terza incursione in assemblea, quindi qualsiasi correzione sarebbe apprezzata. – Straivers
Non conosco D, ho appena visto questa domanda a causa dei tag SSE e inline-asm. D ha qualcosa di simile agli intrinsechi Intel C? '__m128 my_vec = _mm_add_ps (vec1, vec2);'? Se è così, probabilmente farai meglio con quello. Se la sintassi in linea asm di D'è limitata al passaggio dei dati attraverso la memoria, non ai registri, allora [è utile solo se vuoi scrivere un intero ciclo al suo interno, non come un wrapper per alcune istruzioni] (http://stackoverflow.com/ domande/3323445/what-is-the-differenze-tra-asm-e-asm/35.959.859 # 3.595.985). Se supporta istruzioni asm in stile GNU-C, allora usa quello. –