2015-09-20 14 views
9

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

+0

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

+0

Framework phiên bản 4.6 và IsHardwareAccelerated trả về false. –

+0

'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 –

Trả lời

9

tôi đã liên lạc với Microsoft, đã đăng một địa chỉ liên lạc cho Net câu hỏi và mối quan tâm Quê quán: https://msdn.microsoft.com/en-us/vstudio/dotnetnative.aspx

Câu hỏi của tôi đã được gọi Ian Bearman, Công nghệ phần mềm Principal Người quản lý trong Nhóm công nghệ tạo và tối ưu hóa mã của Microsoft:

Hiện tại .NET không tối ưu hóa thư viện System.Numerics và dựa vào triển khai thư viện mặc định. Điều này có thể (đọc: sẽ khả năng) dẫn đến mã được viết bằng System.Numerics để không hoạt động dưới dạng cũng trong .NET Gốc vì nó sẽ chống lại các triển khai CLR khác.

Mặc dù điều này không may, .NET Native hỗ trợ tự động vector hóa đi kèm với việc sử dụng tối ưu hóa C++ được đề cập ở trên. vận chuyển hiện tại.NET Native compiler hỗ trợ SSE2 ISA trong tự động vector trên x86 và x64 và NEON ISA trên ARM.

Ông cũng đề cập rằng họ muốn mang lại từ trình biên dịch C++ khả năng tạo tất cả các hướng dẫn vectơ (AVX, SSE, v.v.) và nhánh dựa trên phát hiện tập lệnh lúc chạy. Sau đó, ông đề xuất rằng nếu việc sử dụng hướng dẫn thực sự quan trọng, thành phần có thể được xây dựng trong C++, có quyền truy cập vào nội tại của trình biên dịch (và có lẽ là khả năng phân nhánh này?) Và sau đó dễ dàng giao tiếp với ứng dụng C# còn lại.

Đối với các lệnh SSE2 bị bỏ qua, tất cả những gì tôi cần làm để biên dịch sang đúng hướng dẫn là thay thế "a = a^b" lặp lại bằng "a^= b". Vì chúng phải là những biểu thức tương đương, có vẻ như đó là một lỗi, nhưng may mắn là một lỗi với cách giải quyết.

+0

Thông tin rất thú vị/hữu ích, cảm ơn bạn đã theo dõi! –

+1

Cảm ơn bạn đã quay trở lại. Đây không phải là những gì tôi đang tìm kiếm nhưng hấp dẫn không kém. Kudo để theo dõi điều này cho phần còn lại của chúng tôi. – EndsOfInvention

Các vấn đề liên quan