15

を使用するいくつかの 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 になる必要があります...しかし、それは私が見ているものではありません。vmovupdvaddupsVector<float>.CountVector<double>.Count

代わりに、私の逆アセンブリには、、、などの命令と次のコードが含まれていmovupsます。movupdaddups

WriteLine($"{Vector<byte>.Count} bytes per operation");
WriteLine($"{Vector<float>.Count} floats per operation");
WriteLine($"{Vector<int>.Count} ints per operation");
WriteLine($"{Vector<double>.Count} doubles per operation");

プロデュース:

16 bytes per operation
4 floats per operation
4 ints per operation
2 doubles per operation

どこが間違っていますか?すべてのプロジェクト設定などを確認するには、プロジェクトをここで入手できます。

4

1 に答える 1

12

あなたのプロセッサは少し時代遅れで、そのマイクロアーキテクチャは Ivy Bridge です。Sandy Bridge の "トック" は、アーキテクチャの変更なしで機能が縮小されます。あなたの宿敵は、 ee_il_dll.cpp、 CILJit::getMaxIntrinsicSIMDVectorLength() 関数にある RyuJIT のこのコードです。

if (((cpuCompileFlags & CORJIT_FLG_PREJIT) == 0) &&
    ((cpuCompileFlags & CORJIT_FLG_FEATURE_SIMD) != 0) &&
    ((cpuCompileFlags & CORJIT_FLG_USE_AVX2) != 0))
{
    static ConfigDWORD fEnableAVX;
    if (fEnableAVX.val(CLRConfig::EXTERNAL_EnableAVX) != 0)
    {
        return 32;
    }
}

CORJIT_FLG_USE_AVX2 の使用に注意してください。お使いのプロセッサはまだ AVX2 をサポートしていません。その拡張機能は Haswell で利用可能になりました。Ivy Bridge の次のマイクロ アーキテクチャ、「ティック」。非常に優れたプロセッサですが、このような発見には大きな驚きがあります。

これについてあなたができることは、買い物に行くことだけです。インスピレーションとして、この投稿で生成されるコードの種類を確認できます。

于 2016-01-20T11:00:05.223 に答える