2016-05-20 22 views
1

このコードをNASM 32ビットSSEからNASM 64-AVXに変換したいと思います。それを簡単に行う方法を見つけることは可能でしょうか?NASM 32ビットSSEコードをNASM 64ビットに変換するAVX

64ビットコードに変換するには、32ビットコードを完全に書き直そうとします。しかし、これは非常に難しい作業であると私は思っています。私はすべてを行うほとんど自動の方法があると思います。

あなたはこのようなプロセスを認識していますか?たとえば、レジ​​スタの名前を置き換える?

例:raxから

  • 変更eaxrbxebx、というように...
  • vmovapsと変更movapsのように...
  • ...

ここに私の32ビットNASMソースコードがあります:

section .text    
global test 

    a   equ  8 
    b   equ  12 
    num   equ   16  
    spuri  equ   20 
    result  equ  24 

test: 
    push ebp    
    mov  ebp, esp   
    push ebx    
    push esi 
    push edi 

    mov   esi, [ebp+a]     
    mov   edi, [ebp+b]     
    mov   ebx, 0    
    mov   ecx, [ebp+num]    
    mov   edx, [ebp+spuri] 
    mov   eax,[ebp+result]     
    xorps  xmm1,xmm1   
    xorps  xmm3,xmm3   

loop1: 
    cmp ecx,0 
    je end 
    movups  xmm0, [esi+ebx]  
    movups  xmm6, [edi+ebx] 
    subps  xmm0, xmm6   
    mulps  xmm0, xmm0   
    sqrtps  xmm0, xmm0 
    addps  xmm1, xmm0   
    add   ebx, 16    
    dec   ecx     
    jnz   loop1 

end: 
    haddps  xmm1,xmm1 
    haddps  xmm1,xmm1 
    addps  xmm1,xmm3 
    movups  [eax],xmm1 

    pop edi      
    pop  esi 
    pop  ebx 
    mov esp, ebp     
    pop ebp      
    ret  

私はこのコードを変換しようとしましたが、良い結果はありませんでした。

+0

なぜ組み込み関数に切り替えるだけではないのですか?これはかなり簡単な操作であり、Cや組み込み関数を使って書き直すと、はるかに簡単に保守、デバッグ、移植が可能です。(単純なスカラーのCコードで最初にそれを表現しようとしても、コンパイラが自動的にベクトル化するかどうかを確認することもできます) –

+0

また、 'spuri'パラメータは未使用のようですか? (編集:OK - これは本当に[あなたの前の質問]の更新ですように見える(http://stackoverflow.com/questions/37257665/c-calling-conventions-32bit-to-nasm-with-float-movups- movupd-difference) 'loop1'の後にもう一つのループがあったのですか?) –

+0

これはコードの一部です。 SSEだけの組み込み関数は使用できません。このコードを64ビットでどのように変換できますか? –

答えて

1

32bitから64bitへの移植は、SSEから256b AVXへの移植から直交です。しかし、一度に両方を実行するということは、各タスクに対して1回ではなく、コードのすべての行を一度だけ実行する必要があることを意味します。

SSE-> AVX:シャッフルなどがある場合は、既存のSSE命令のAVXバージョンでは基本的に2つの「レーン」で2つの別々の128b操作が行われるため、扱いにくいです。

32-> 64b:ABIはargの渡し方が異なり、保存/復元が必要です。ポインタは一般に64bレジスタに入る必要がありますが、可能であれば32ビットレジスタを使用します。 32bit regを書き込むと、64b reg全体がゼロ拡張されるため、xor eax,eaxのレジスタはゼロになります。 xor rax,raxは命令バイトの無駄です。このレベルの最適化を気にしない場合は、Cで記述してください。

スタティック/グローバルデータにRIP相対アドレッシングを使用してください。

リンクについては、のタグwikiを参照してください。


あなたは、mulps xmm0, xmm0/sqrtps xmm0, xmm0を書いた人よりもASMでより良い人を持って、その後ASMにあきらめ、あなたの最大のスピードアップは、既存のコードベースにfixing stuff like thatから来るC.にあなたのコードを書き換えていない場合は、ベクトル幅を2倍にすることによる潜在的な2倍の高速化よりもさらに優れています。

良い最適化コンパイラであれば、最近多くの単純なスカラーループを自動ベクトル化することができます。 gccまたはclangの最新バージョンを使用してください。

C/C++ intrinsicsを使用することもできます。同じ手動ベクトル化で32または64ビットの実行可能ファイルをビルドすることができます。

+1

確かに、この[XY問題](http://meta.stackexchange.com/q/66377/142198)の正しい解決策は、元の非効率的かつひどく書かれた32ビットのアセンブリコードを元に戻し、Cできるだけ重い吊り上げにしてから、最後の手段として明示的なSIMDコードを実行するためにその組み込み関数を使用しないようにします。一度にすべての移植性と効率の問題を解決し、長期的にはコードをより堅牢で、保守性が高く、ポータブルにします。 –

関連する問題