問題タブ [ryujit]
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.
c# - SIMD 組み込み関数を使用する場合のこれらの追加の逆アセンブリ命令は何ですか?
RyuJIT で SIMD 命令を使用すると、どのような高速化が得られるかをテストしていますが、予期しない逆アセンブリ命令が表示されます。このコードは、RyuJIT チームの Kevin Frei によるこのブログ投稿と関連する投稿 (こちら) に基づいています。関数は次のとおりです。
私が照会している逆アセンブリのセクションは、配列の値をVector<float>
. 逆アセンブルのほとんどは、Kevin と Sasha の投稿にあるものと似ていますが、逆アセンブルに表示されないいくつかの追加の手順 (混乱した注釈と共に) を強調しています。
ループ範囲チェックが期待どおりであることに注意してください。
との追加の比較がある理由がわかりませんeax
。これらの余分な指示が表示される理由と、それらを取り除くことが可能かどうかを誰かが説明できますか?
プロジェクト設定に関連している場合は、 github で同じ問題を示す非常によく似たプロジェクトがあります(FloatSimdProcessor.HwAcceleratedSumInPlace()
またはを参照UShortSimdProcessor.HwAcceleratedSumInPlaceUnchecked()
)。
c# - System.Numerics.VectorX をラップするのに費用がかかる - なぜ?
TL;DR : System.Numerics.Vectors 型のラップはなぜコストがかかるのですか?それについて何かできることはありますか?
次のコードを検討してください。
これは (x64) に JIT します:
および x86:
これを構造体でラップすると、たとえば
と変更GetIt
、例えば
JITted の結果は、ネイティブ型を直接使用した場合とまったくAddThem
同じです ( 、およびSomeWrapper
オーバーロードされた演算子とコンストラクターはすべてインライン化されています)。予想通り。
ここで、SIMD 対応の型でこれを試してみると、たとえばSystem.Numerics.Vector4
次のようになります。
次のように JIT されます。
ただし、構造体でラップするVector4
と (最初の例と同様):
私のコードは、さらに多くのコードに JIT されています。
JITは何らかの理由でレジスタを使用できず、代わりに一時変数を使用することを決定したようですが、その理由はわかりません。最初はアラインメントの問題かもしれないと思ったのですが、最初に両方を xmm0 にロードしてからメモリへのラウンドトリップを決定する理由がわかりません。
ここで何が起こっているのですか?さらに重要なことに、それを修正できますか?
このように構造をラップしたい理由は、API を使用する多くのレガシー コードがあり、その実装が SIMD の利点の恩恵を受けるからです。
編集:したがって、coreclr ソースを掘り下げた後、実際には System.Numerics クラスについて特別なことではないことがわかりました。System.Numerics.JitIntrinsic
メソッドに属性を追加するだけです。その後、JIT は私の実装を独自のものに置き換えます。JitIntrinsic
プライベートですか?問題ありません。コピーして貼り付けるだけです。ただし、元の質問はまだ残っています (回避策がある場合でも)。
c# - RyuJIT が SIMD 組み込み関数を十分に活用していない
を使用するいくつかの C# コードを実行していますSystem.Numerics.Vector<T>
が、私が知る限り、SIMD 組み込み関数の利点を十分に活用できていません。Visual Studio Community 2015 と Update 1 を使用しています。私の clrjit.dll は v4.6.1063.1 です。
AVX 命令セット拡張を実装するIntel Core i5-3337U Processorで実行しています。したがって、256 ビット レジスタでほとんどの SIMD 命令を実行できるはずです。たとえば、逆アセンブリには、、、、などの命令が含まれている必要があり、8vmovups
を返す必要があり、4 になる必要があります...しかし、それは私が見ているものではありません。vmovupd
vaddups
Vector<float>.Count
Vector<double>.Count
代わりに、私の逆アセンブリには、、、などの命令と次のコードが含まれていmovups
ます。movupd
addups
プロデュース:
どこが間違っていますか?すべてのプロジェクト設定などを確認するには、プロジェクトをここで入手できます。
.net - .NET JIT コンパイラーはどのような条件下で自動ベクトル化を実行しますか?
新しい RyuJIT コンパイラはベクトル (SIMD) CPU 命令を生成しますか? また、いつ生成しますか?
補足: System.Numerics 名前空間には、ネイティブ コードに直接コンパイルするかどうかにかかわらず、CPU、CLR バージョン、JITer バージョンに応じて SIMD 命令を生成する場合と生成しない場合がある Vector 操作を明示的に使用できる型が含まれています。この質問は、非ベクター コード (C# や F# など) がいつ SIMD 命令を生成するかに関するものです。
.net - RyuJIT と Roslyn の違いは何ですか?
RyuJIT は JIT よりも高速なコンパイラであることがわかりました。しかし、これは .NET 4.6 の新しい標準なのか、それとも Roslyn なのか?
それとも、コンパイル プロセス中に API を公開する必要があるときに Roslyn が使用されるのでしょうか。
それらの目的と、それらが見つかるフレームワークとの間で混乱しています。誰かが違いを説明できますか?
c# - RyuJIT - ushort と Equals のオーバーライドに関するバグ (64 ビット)
32 ビット マネージド アプリケーションを 64 ビットに移植しているときに、構造体内の Equals() オーバーライドによる奇妙な動作を観察しました。
再現ファイルはgithubにあります。
バグを再現するには、「最適化」フラグをオンにしてライブラリをコンパイルする必要があります。これは、リリース構成のデフォルトです。消費する TestApp は、最適化せずにコンパイルする必要があります。64 ビット アプリとして起動するには、Prefer 32 ビットを無効にする必要があります。github の注意事項を参照してください。
ライブラリには、単純なコード行で実装される IEquatable インターフェイスを実装する構造体が含まれています。
このコードは、ushort/UInt16 型の Equals メソッドを呼び出します。提案された構成でソリューションをビルドすると、32767 を超える値はすべて失敗します。32768 の ushort 値で Equal を呼び出し、'other' の値も 32768 です。ただし、Equals() は 32767 を超えるすべての値に対して false を返します。
「==」演算子を使用するようにメソッドを変更すると、コードは機能します。また、タイプを構造体からクラスに変更すると、コードは期待どおりに実行されます。
これは RyuJIT-Compiler のバグだと思います。従来の JIT コンパイラを使用すると、コードは正常に動作します。
Visual Studio 2015 と TargetFramework 4.6.2 のさまざまな Windows バージョンでテスト済み。