Tôi đang cố gắng sử dụng System.Numerics.Vector (T) để vector hóa một thuật toán và tận dụng các hoạt động SIMD của CPU. Tuy nhiên, việc triển khai vector của tôi chậm hơn đáng kể so với triển khai ban đầu của tôi. Có bất kỳ thủ thuật nào để sử dụng các Vectơ có thể chưa được ghi chép? Việc sử dụng cụ thể ở đây là để cố gắng tăng tốc Xors của kb dữ liệu.Sử dụng Vector <T> cho SIMD trong nền tảng Windows phổ quát
Thật không may, hầu như tất cả tài liệu tôi có thể tìm thấy trên tài liệu này dựa trên phiên bản tiền phát hành của RyuJIT và tôi không biết tài liệu đó có thể chuyển sang .NET Native bao nhiêu.
Khi tôi kiểm tra việc tháo gỡ trong một hoạt động Vector xor, nó cho thấy:
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
Tại sao nó không sử dụng các thanh ghi XMM và hướng dẫn SIMD cho việc này? Điều lạ lùng là các lệnh SIMD đã được tạo ra cho một phiên bản của mã này mà tôi đã không vectorized một cách rõ ràng, nhưng chúng chưa bao giờ được thực thi, ủng hộ các thanh ghi và hướng dẫn thông thường.
Tôi đảm bảo rằng tôi đang chạy với phiên bản Release, x64, Optimize được bật. Tôi thấy hành vi tương tự với trình biên dịch x86. Tôi có phần mới làm quen với các công cụ cấp máy, vì vậy có thể có điều gì đó đang diễn ra ở đây mà tôi không hiểu đúng.
Phiên bản khung là 4.6, Vector.IsHardwareĐược tăng tốc là sai khi chạy.
Cập nhật: "Biên dịch với .NET Chuỗi công cụ gốc" là thủ phạm. Kích hoạt nó gây ra Vector.IsHardwareAccelerated == false; Vô hiệu hóa nó gây ra Vector.IsHardwareAccelerated == true. Tôi đã xác nhận rằng khi .NET Native bị tắt, trình biên dịch sẽ tạo ra các lệnh AVX bằng cách sử dụng thanh ghi ymm. Điều này dẫn đến câu hỏi ... tại sao SIMD không được bật trong .NET Native? Và có cách nào để thay đổi điều đó không?
Cập nhật Tangent: tôi phát hiện ra rằng lý do mã mảng auto-SSE-vectorized đã không được thực hiện là do trình biên dịch đã chèn một lệnh trông thấy nếu khi bắt đầu của mảng là tại một địa chỉ thấp hơn hơn một trong những thành phần cuối cùng của mảng, và nếu nó là, chỉ cần sử dụng thanh ghi bình thường. Tôi nghĩ rằng đó phải là một lỗi trong trình biên dịch, bởi vì sự bắt đầu của một mảng phải luôn luôn ở một địa chỉ thấp hơn so với các phần tử cuối cùng của nó theo quy ước. Đó là một phần của bộ hướng dẫn kiểm tra địa chỉ bộ nhớ của mỗi mảng toán hạng, tôi nghĩ rằng để đảm bảo chúng không bị chồng chéo. Tôi đã đệ trình báo cáo lỗi của Microsoft Connect cho việc này: https://connect.microsoft.com/VisualStudio/feedback/details/1831117
Phiên bản khung này là gì? Tăng tốc phần cứng có được báo cáo là 'true' không? – usr
Framework phiên bản 4.6 và IsHardwareAccelerated trả về false. –
'tại sao SIMD không được kích hoạt trong .NET Native?' Tôi chỉ có thể mạo hiểm đoán: SIMD được xử lý bởi JIT (trình biên dịch chỉ trong thời gian, thứ biến đổi lúc chạy mã IL thành mã gốc). .NET native hoàn toàn bỏ qua JIT bằng cách tạo ra một assembly hoàn toàn bản địa (không cần dịch). Tôi đoán họ chỉ đơn giản là không thực hiện hỗ trợ SIMD vào chuỗi công cụ bản địa .NET. Hoặc bởi vì họ không có thời gian, hoặc vì .NET native có thể được sử dụng để tạo ra các chương trình đang chạy trên các CPU không có các thanh ghi SIMD –