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?
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
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
@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