我試圖使用System.Numerics.Vector(T)矢量化算法並利用CPU的SIMD操作。但是,我的矢量實現比我原來的實現要慢很多。有沒有使用可能沒有記錄的矢量的技巧?這裏的具體用處是試圖加快Xors的kb數據。使用矢量<T> SIMD在通用Windows平臺
不幸的是,我幾乎可以找到的所有文檔都基於RyuJIT的預發佈版本,我不知道有多少材料可移植到.NET Native。
當我一個Vector XOR操作過程中檢查拆卸,它表明:
00007FFB040A9C10 xor eax,eax
00007FFB040A9C12 mov qword ptr [rcx],rax
00007FFB040A9C15 mov qword ptr [rcx+8],rax
00007FFB040A9C19 mov rax,qword ptr [r8]
00007FFB040A9C1C xor rax,qword ptr [rdx]
00007FFB040A9C1F mov qword ptr [rcx],rax
00007FFB040A9C22 mov rax,qword ptr [r8+8]
00007FFB040A9C26 xor rax,qword ptr [rdx+8]
00007FFB040A9C2A mov qword ptr [rcx+8],rax
00007FFB040A9C2E mov rax,rcx
爲什麼它不使用這個XMM寄存器和SIMD指令?奇怪的是,SIMD指令是爲我沒有明確向量化的代碼版本生成的,但它們從未被執行,而是支持常規寄存器和指令。
我確保我使用Release,x64,Optimize代碼啓用。我看到了與x86編譯類似的行爲。我在機器級別上有點新手,所以它有可能出現這種情況,我沒有正確理解。
框架版本是4.6,Vector.IsHardwareAccelerated在運行時爲false。
更新:「編譯與.NET Native工具鏈」是罪魁禍首。啓用它會導致Vector.IsHardwareAccelerated == false;禁用它會導致Vector.IsHardwareAccelerated == true。我已經確認,當禁用.NET Native時,編譯器正在使用ymm寄存器生成AVX指令。這導致了這個問題......爲什麼在.NET Native中未啓用SIMD?有什麼方法可以改變它?
更新Tangent:我發現auto-SSE向量化數組代碼沒有被執行的原因是編譯器插入了一條指令,看看數組的起始位置是否在較低的地址而不是數組中的最後一個元素,如果是,則只使用正常的寄存器。我認爲這肯定是編譯器中的一個bug,因爲按照慣例,數組的起始位置應該總是比最後一個元素的地址低一些。它是測試每個操作數數組的內存地址的一組指令的一部分,我認爲要確保它們不重疊。我提起了微軟連接錯誤報告此:https://connect.microsoft.com/VisualStudio/feedback/details/1831117
這是什麼框架版本?硬件加速是否被報告爲「真實」? – usr
Framework版本4.6和IsHardwareAccelerated返回false。 –
'爲什麼在.NET Native中未啓用SIMD?'我只能冒險猜測:SIMD是由JIT(即時編譯器,即在運行時IL代碼轉換爲本地代碼的東西)處理的。 .NET native通過創建一個純粹的本地程序集(無需翻譯)完全繞過JIT。我想他們根本沒有在.NET本地工具鏈中實現SIMD支持。因爲他們還沒有時間,或者因爲.NET本地可以用來創建在沒有SIMD寄存器 –