2016-09-17 11 views
2

ゼロにされた128ビットのレジスタがあります。左にシフトしてバイトを追加します。私はそれをシフトすることができます:16バイトをXMMレジスタに移動する方法(最大)

pslldq xmm0, 1 

...しかし、私は空のスペースにalをコピーしたいと思います。次のようなものがあります:

or xmm0, al 

もちろん動作しません。私は影響を受けた最も低い8ビットのみを必要とします。これはループの中で、レジスタの充填にalの連続する値が使用されます。だから私は何らかのmov命令や他の選択肢が必要です。

左の8ビットをシフトして挿入するのは理想的ですが、それは存在しないと思います。

私は、x86-64命令セットのデータで騒ぎ回るのに多くの時間を費やしましたが、私が欲しいことをするための何かを見つけることができません。それはできますか?

更新:pinrbを試した後、私のコードロジックにエラーが見つかりました。 pinsrbは素晴らしいでしょうが、残念ながらレジスタではなく即時インデックスしか使用できません。

私は連続していない場所からバイトを取っているので、一度に1バイトずつ行う必要があると思います。バイト数は1から16までの任意の数にすることができます。最初のバイトIグラブはxmm0の最下位バイトで終了し、次のバイトは次のバイトになります。

+1

あなたはSSE4.1の 'pinsrb xmm0、eax、1'を望みますが、それを16回繰り返すのは遅いです。ベクトルを毎回シフトするのではなく、16個の異なるインデックスを使用するだけです。 –

+0

index = 0、1、2、...でpinsrbを使うことができるように、挿入ループをアンロールします(終了テストを保つ)ので、より効率的な処理が可能です(特に、挿入されます)、それは動作します。 –

+0

周辺コードに関する未知数が多すぎるため、最適なものについて具体的なアドバイスはできません(シャッフルスループット、待ち時間、uopスループット、キャッシュミスなどにボトルネックがあるなど)。多くの場合、これらのバイト・ギャザリングは数多くありますか?それ以外には他にもたくさんの計算がありますか?)場合によっては、16Bスクラッチ・アレイにバイトをコピーし、ベクトル・ロードを行うのが最適な場合もあります。店舗運送の失敗は問題ではなく、これらの店舗は問題ではありませんでした)。 –

答えて

3

Intel's intrinsics guideは、ベクトル命令を見つけるのに便利です。これは、asmニーモニックと組み込み関数をリストします(そして、エントリがエントリ全体のテキストと一致するので、組み込み関数の代わりにニーモニックで検索できます)。

インテルのPDFリファレンスマニュアルにもインデックスがあります。 insn set refマニュアルはvolume 2です。タグwikiのIntelのマニュアルへのリンクを参照してください。


PINSRBはあなたが尋ねたものとまったく同じですが、そうしないでください。マージ命令(PINSR *)付きの整数 - >ベクトル挿入は挿入位置のインデックスを取るため、左に移動する必要はありません。 (そして、すでにシャッフルが必要なので、毎回同じ位置を使用し、ベクトルをシフトすることはパフォーマンスには悪い)

この問題については、ベクトルに16バイトを別々に挿入するのが最も効率的なアプローチではありません。整数レジスタでそれらを4または8のグループにまとめる方が良い方法かもしれません。

;; b0 .. b15 are whatever addressing mode you want. 
;; if you could get more than 1 of b0..b15 with a single vector load (i.e. there is some locality in the source bytes) 
;; then DON'T DO THIS: do vector loads and shuffle + combine (pshufb if needed) 

movzx eax, byte [b0] 
mov ah, byte [b1] # partial-reg merging after this is free on Haswell, cheap on SnB/IvB, and very slow on CPUs before Sandybridge. 
movzx edx, byte [b2] 
mov dh, byte [b3] 
shl edx, 16 
or  edx, eax 
movd xmm0, edx  # cheaper than pinsrd xmm0, edx, 0. Also zeros the rest of the vector 

movzx eax, byte [b4] 
mov ah, byte [b5] 
movzx edx, byte [b6] 
mov dh, byte [b7] 
shl edx, 16 
or  edx, eax 
pinsrd xmm0, edx, 1 
... 
pinsrd xmm0, edx, 2 
... 
pinsrd xmm0, edx, 3 

SSE4を想定できない場合は、pinsrw(SSE2)を使用できます。または、movdとシャッフルベクトルをPUNPCKLDQ/PUNPCKLDQDと一緒に使用する方がよいでしょう。 (そのリンクは、IntelのマニュアルのHTMLの抜粋です)。

Agner Fog's Optimizing Assembly guide(および命令テーブル/マイクロカードガイド)を参照して、どの命令が実際に良好であるかを判断してください。

関連する問題