問題タブ [sse]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票する
4 に答える
3203 参照

c - SSE組み込み関数を使用して、4つのドット積をCの連続した配列に格納する最も効率的な方法

SSE組み込み関数を使用して、Intelx86Nehalemマイクロアーキテクチャ用にいくつかのコードを最適化しています。

私のプログラムの一部は4つの内積を計算し、各結果を配列の連続したチャンクの前の値に追加します。すなわち、

各ドット積の結果を保持するために4つの一時xmmレジスタを使用してこれを実行していることに注意してください。各xmmレジスタでは、結果は他の一時的なxmmレジスタに対して一意の32ビットに配置され、最終結果は次のようになります。

tmp0=R0-ゼロ-ゼロ-ゼロ

tmp1=ゼロ-R1-ゼロ-ゼロ

tmp2=ゼロ-ゼロ-R2-ゼロ

tmp3=ゼロ-ゼロ-ゼロ-R3

次の手順でそれらを合計することにより、各tmp変数に含まれる値を1つのxmm変数に結合します。

最後に、ドット積の4つの結果すべてを含むレジスタを配列の連続部分に追加して、配列のインデックスがドット積によって増分されるようにします(C_0nは、更新される配列に現在ある4つの値です)。 ; C_2は、これら4つの値を指すアドレスです):

ドット積の結果を取得して、それらを配列の連続するチャンクに追加するための、より回りくどく、より効率的な方法があるかどうかを知りたいです。このようにして、ゼロ以外の値が1つしかないレジスタ間で3つの加算を実行しています。これを回避するためのより効果的な方法があるはずです。

私はすべての助けに感謝します。ありがとうございました。

0 投票する
1 に答える
1962 参照

c - SSEシフト整数

SSEでのシフトがどのように機能するかを理解しようとしていますが、gdbの出力がわかりません。SSE4を使用すると、8つの16ビット符号なし整数を保持する128ビットベクトルがあります(を使用uint16_t)。次に、組み込み関数を使用し_mm_cmpgt_epi16てそれらをある値と比較します。この関数は、intを格納するために使用されるビットにすべての0または1ビットを入れます。これまでのところ、gdbを使用すると次のようになります。

次に、それらを右にシフトしたいので(それは正しいですか?)、それが本当の場合に備えて、数値1を取得します。次に、GDBは私が理解できない出力を提供します。

最初のものと同じ長さでもありません、なぜこれですか?試してみるために、次の組み込み関数を使用して1ビット右にシフトしました。

16ビットブロックごとに右端でゼロが1つだけシフトすることを期待していました。

アップデート:

私はビットマスクを使って物事をテストするための小さな例を書きました、それはうまくいきます、しかし私はまだgdbsの振る舞いを理解していません:


私のgdbバージョン:GNU gdb 6.3.50-20050815 (Apple version gdb-1472) (Wed Jul 21 10:53:12 UTC 2010)

コンパイラフラグ:-Wall -g -O0 -mssse3 -msse4 -std=c99

0 投票する
2 に答える
5257 参照

c - What's the most efficient way to load and extract 32 bit integer values from a 128 bit SSE vector?

I'm trying to optimize my code using SSE intrinsics but am running into a problem where I don't know of a good way to extract the integer values from a vector after I've done the SSE intrinsics operations to get what I want.

Does anyone know of a good way to do this? I'm programming in C and my compiler is gcc version 4.3.2.

Thanks for all your help.

0 投票する
1 に答える
1618 参照

c - 64ビット固有のsimd組み込み

SSE2では次のユニオン宣言を使用しています。

アイデアは、2つの符号なしlong変数(64ビット長)をそれぞれaとbに割り当て、それらをXORして、結果をcに配置することです。

ここでは明示的な割り当て(a.data[0] = something)が機能しますが、より多くの時間が必要です。

組み込み関数を使用する予定です。を使用する_mm_set_epi64 (unsigned long x, unsigned long y)と、変数を要求し__m64ます。これらの変数をキャストすると正常に(__m64)x機能しますが、間違った結果になります。

上記のコードはエラーになります:

いくつかの代替案(組み込み関数)を提案できますか?

0 投票する
4 に答える
4072 参照

c - SIMDコードはスカラーコードよりも実行が遅くなります

elmaelmcは両方ともunsigned long配列です。res1とですres2

forループ内には、要素のXORの非simdバージョンとsimdバージョンの両方が含まれています。2番目のforループ内の最初の2行は、明示的なXORを実行しますが、残りは同じ操作のsimdバージョンを実装します。

このループは外部から何百回も呼び出されるため、このループを最適化すると、合計計算時間を短縮できます。

問題は、simdコードがスカラーコードよりも何倍も遅く実行されることです。

編集:部分的な展開を行いました

しかし、結果はあまり変わりません。それでもスカラーコードの2倍の時間がかかります。

0 投票する
2 に答える
2443 参照

c - SIMD コードとスカラー コード

次のループは何百回も実行されます。
elma and elmc are both unsigned long (64-bit) arrays, so is res1 and res2.

for ループ内では、スカラー バージョンのコード (コメント付き) は、simd コードよりも 2 倍速く実行されます。上記の行の cachegrind 出力 (命令読み取り) を以下に示します。

行1:668,460,000 2 2 2
行目2行目:668,460,000 1 1
行3:89,985,000 1 1
行4:89,985,000 1 1 行 5
:617,040,000 2 2 2
行6:44,992,500 0 0
行7:44,992,500 0 : 128,550,000 0 0 行 10: 。. . 11 行目: 205,680,000 0 0 12 行目: 205,680,000 0 0




上の図から、コメント化された (スカラー コード) は、simd コードよりもはるかに少ない数の命令を必要とするように見えます。

このコードを高速化するにはどうすればよいですか?

0 投票する
1 に答える
776 参照

gcc - 上位レベルの SSE フラグは、GCC/clang の下位フラグを意味しますか?

たとえば、-msse4 を使用する場合、-mssse3、-msse3、-msse2 なども使用することを意味しますか?それとも、これらのフラグも明示的に追加する必要がありますか?

0 投票する
2 に答える
6944 参照

c++ - 整列された型と値による引数の受け渡し

整列された型または整列された型を持つ構造体を値で渡すことは、一部の実装では機能しません。一部のメソッド(サイズ変更など)は引数を値で受け取るため、これによりSTLコンテナーが破損します。

Visual Studio 2008でいくつかのテストを実行しましたが、値渡しがいつどのように失敗するかが完全にはわかりません。私の主な関心事は関数fooです。正常に動作しているように見えますが、インライン化またはその他の偶然の結果である可能性がありますか?署名をvoidfoo(const __m128&)に変更するとどうなりますか?

ご意見をいただければ幸いです。ありがとうございました。

編集。値の受け渡しの問題が残っているため、整列されたアロケータでもSTLは失敗します。

このリンクが値で__m128を渡すことがわかりました

0 投票する
1 に答える
6100 参照

c++ - SSE:__m128と__m128iを2つの__m128dに変換します

2つの関連する質問。

これは、私のコードがかなり大量のデータを処理するために必要なことです。これは内部ループ内で行われ、パフォーマンスが重要です。

  1. __int32の配列をdoubleに変換します(または__m128iを2つの__m128dに変換します)。
  2. floatの配列をdoubleに変換します(または__m128を2つの__m128dに変換します)。

基本的に、次のシグネチャを持つ関数が必要です。

入力ポインタと出力ポインタが揃っており、要素の数は4の倍数です。主な問題は、__m128を2つの__m128dにすばやく解凍する方法です。

0 投票する
5 に答える
2832 参照

c++ - SSE2:倍精度ログ機能

ログ機能のオープンソース(ライセンスの制限なし)の実装が必要です。

Intel Short Vector Math Library(ICCの一部)で利用できますが、ICCは無料でもオープンソースでもありません。組み込み関数のみを使用した実装を探しています。

特別な有理関数近似を使用する必要があります。cmathログとほぼ同じくらい正確なもの、たとえば10進数の9〜10桁が必要ですが、より高速です。