2014-11-11 13 views
7

Tôi đang cố gắng sử dụng vector hóa trong trình biên dịch của mình (Microsoft Visual Studio 2013). Một trong những vấn đề tôi đang gặp phải là nó không muốn sử dụng AVX2. Trong khi điều tra vấn đề này, tôi đã xây dựng ví dụ sau, tính toán tổng 16 số, mỗi số 16 bit.Tại sao việc vector hóa tự động của MSVC không sử dụng AVX2?

int16_t input1[16] = {0}; 
int16_t input2[16] = {0}; 
... // fill the arrays with some data 

// Calculate the sum using a loop 
int16_t output1[16] = {0}; 
for (int x = 0; x < 16; x++){ 
    output1[x] = input1[x] + input2[x]; 
} 

Trình biên dịch vectorizes mã này, nhưng chỉ lệnh SSE:

vmovdqu xmm1, xmmword ptr [rbp+rax] 
lea  rax, [rax+10h] 
vpaddw xmm1, xmm1, xmmword ptr [rbp+rax+10h] 
vmovdqu xmmword ptr [rbp+rax+30h], xmm1 
dec  rcx 
jne  main+0b0h 

Để đảm bảo trình biên dịch có tùy chọn để tạo ra mã AVX2, tôi đã viết những tính toán tương tự như sau:

// Calculate the sum using one AVX2 instruction 
int16_t output2[16] = {0}; 
__m256i in1 = _mm256_loadu_si256((__m256i*)input1); 
__m256i in2 = _mm256_loadu_si256((__m256i*)input2); 
__m256i out2 = _mm256_add_epi16(in1, in2); 
_mm256_storeu_si256((__m256i*)output2, out2); 

Tôi thấy rằng hai phần mã tương đương (nghĩa là, output11 bằng output2 sau khi chúng được thực hiện).

Và nó ra hướng dẫn AVX2 cho phần thứ hai của mã:

vmovdqu ymm1, ymmword ptr [input2] 
vpaddw ymm1, ymm1, ymmword ptr [rbp] 
vmovdqu ymmword ptr [output2], ymm1 

Tôi không muốn phải viết lại mã của tôi để sử dụng intrinsics, tuy nhiên: khi nó được viết như một vòng lặp là tự nhiên hơn nhiều, là tương thích với bộ vi xử lý cũ (SSE), và có những ưu điểm khác.

Vậy làm cách nào tôi có thể tinh chỉnh ví dụ của mình để làm cho trình biên dịch có thể vector hóa nó theo cách AVX2?

+2

Tôi chỉ đoán ở đây nhưng từ những gì tôi đã thấy về các cuộc đàm phán trên AVX trong Visual Studio việc thực hiện vẫn còn chưa trưởng thành và được biết là không tận dụng lợi thế của tất cả các tối ưu có thể. Một khả năng khác là người tối ưu hóa đã quyết định rằng hiệu suất tốt nhất là không sử dụng lệnh AVX2 trong mọi hoàn cảnh, nơi nó có thể thực hiện được. Ví dụ, có những tình huống mà lệnh AVX có thể gây ra lỗi nhớ cache có nghĩa là nó thực sự kết thúc chậm hơn so với cách tiếp cận ngây thơ hơn. – sjdowling

+0

Tải xuống CPU-z ví dụ và kiểm tra xem CPU của bạn có hỗ trợ AVX hoặc AVX2 hay không. Nếu không, tôi đặt cược đây là lý do tại sao Visual Studio chặn thiết lập của bạn – NirMH

+0

@NirMH Tôi nghĩ rằng nó phải rõ ràng từ mã của tôi rằng nó hỗ trợ AVX2. Ý tôi là, phần thứ hai của mã của tôi liên quan đến một lệnh như vậy. Và tôi đã đề cập rằng nó tạo ra một kết quả chính xác (kiểm tra không phải là mã nhưng tôi thực sự đã kiểm tra). – anatolyg

Trả lời

0

Visual Studio dễ dàng tạo mã AVX2 khi thực hiện số học dấu phẩy động. Tôi đoán điều này là đủ để tuyên bố rằng "VS2013 hỗ trợ AVX2".

Tuy nhiên, không có vấn đề gì tôi đã làm, VS2013 không sản xuất mã AVX2 để tính toán số nguyên (không phải int16_t cũng không int32_t làm việc), vì vậy tôi đoán này không được hỗ trợ ở tất cả (gcc sản xuất AVX2 cho mã của tôi tại phiên bản 4.8. 2, không chắc chắn về các phiên bản trước đó).

Nếu tôi phải thực hiện các phép tính trên int32_t, tôi có thể xem xét chuyển đổi chúng thành float và ngược lại. Tuy nhiên, kể từ khi tôi sử dụng int16_t, nó không giúp đỡ.

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