Trước khi thay thế rất nhiều của tôi "cũ" cho vòng với phạm vi dựa cho vòng, tôi chạy một số thử nghiệm với visual studio 2013:vC++ không còn vectorize đơn giản cho vòng với cú pháp phạm vi dựa trên
std::vector<int> numbers;
for (int i = 0; i < 50; ++i) numbers.push_back(i);
int sum = 0;
//vectorization
for (auto number = numbers.begin(); number != numbers.end(); ++number) sum += *number;
//vectorization
for (auto number = numbers.begin(); number != numbers.end(); ++number) {
auto && ref = *number;
sum += ref;
}
//definition of range based for loops from http://en.cppreference.com/w/cpp/language/range-for
//vectorization
for (auto __begin = numbers.begin(),
__end = numbers.end();
__begin != __end; ++__begin) {
auto && ref = *__begin;
sum += ref;
}
//no vectorization :(
for (auto number : numbers) sum += number;
//no vectorization :(
for (auto& number : numbers) sum += number;
//no vectorization :(
for (const auto& number : numbers) sum += number;
//no vectorization :(
for (auto&& number : numbers) sum += number;
printf("%f\n", sum);
nhìn tháo gỡ, tiêu chuẩn cho vòng đều vectorized:
00BFE9B0 vpaddd xmm1,xmm1,xmmword ptr [eax]
00BFE9B4 add ecx,4
00BFE9B7 add eax,10h
00BFE9BA cmp ecx,edx
00BFE9BC jne main+140h (0BFE9B0h)
nhưng phạm vi dựa cho vòng không:
00BFEAC6 add esi,dword ptr [eax]
00BFEAC8 lea eax,[eax+4]
00BFEACB inc ecx
00BFEACC cmp ecx,edi
00BFEACE jne main+256h (0BFEAC6h)
Có lý do nào tại sao trình biên dịch không thể vector hóa các vòng này?
Tôi thực sự muốn sử dụng cú pháp mới, nhưng mất vectorization quá xấu.
Tôi chỉ thấy this question, vì vậy tôi đã cố gắng /Qvec-report:2
cờ, cho một lý do khác:
loop not vectorized due to reason '1200'
đó là:
Vòng chứa dependences dữ liệu loop-thực mà ngăn chặn vector hóa. Lặp lại khác nhau của vòng lặp can thiệp với nhau sao cho vectơ vòng lặp sẽ tạo ra các câu trả lời sai, và trình tự động vectơ không thể tự chứng minh rằng không có sự phụ thuộc dữ liệu như vậy.
Đây có phải là lỗi giống nhau không? (Tôi cũng đã thử với trình biên dịch vC++ cuối cùng "Tháng 11 năm 2013 CTP")
Tôi có nên báo cáo nó trên MS kết nối không?
chỉnh sửa
Du để bình luận, tôi đã làm bài kiểm tra tương tự với một mảng int liệu thay vì một vector, do đó không có lớp học iterator là tham gia, chỉ con trỏ thô.
Bây giờ tất cả các vòng được vector hóa ngoại trừ hai vòng "mô phỏng dựa trên dải ô".
Compiler nói điều này là do lý do '501':
biến cảm ứng không phải là địa phương; hoặc giới hạn trên không phải là bất biến vòng lặp.
Tôi không có được những gì đang xảy ra ...
const size_t size = 50;
int numbers[size];
for (size_t i = 0; i < size; ++i) numbers[i] = i;
int sum = 0;
//vectorization
for (auto number = &numbers[0]; number != &numbers[0] + size; ++number) sum += *number;
//vectorization
for (auto number = &numbers[0]; number != &numbers[0] + size; ++number) {
auto && ref = *number;
sum += ref;
}
//definition of range based for loops from http://en.cppreference.com/w/cpp/language/range-for
//NO vectorization ?!
for (auto __begin = &numbers[0],
__end = &numbers[0] + size;
__begin != __end; ++__begin) {
auto && ref = *__begin;
sum += ref;
}
//NO vectorization ?!
for (auto __begin = &numbers[0],
__end = &numbers[0] + size;
__begin != __end; ++__begin) {
auto && ref = *__begin;
sum += ref;
}
//vectorization ?!
for (auto number : numbers) sum += number;
//vectorization ?!
for (auto& number : numbers) sum += number;
//vectorization ?!
for (const auto& number : numbers) sum += number;
//vectorization ?!
for (auto&& number : numbers) sum += number;
printf("%f\n", sum);
Dường như trình biên dịch không thể xem xét thông qua loại trình lặp. Hãy thử sử dụng mô phỏng 'for' dựa trên phạm vi bằng cách sử dụng' & v [0] 'và' & v [0] + v.size() 'để xác nhận sự nghi ngờ này. –
@ DietmarKühl Nếu tôi đã hiểu một cách chính xác, tôi đã cố gắng: \t \t cho (tự động __begin = & số [0], \t \t __end = & số [0] + numbers.size(); \t \t __begin = __end; +! + __ bắt đầu) { \t \t tự động && ref = * __ bắt đầu; \t \t tổng cộng + = ref; \t} Nhưng điều này cũng vector hóa. – ThreeStarProgrammer57
Nếu phiên bản sử dụng con trỏ vector hóa vòng lặp, rõ ràng trình vòng lặp gói con trỏ làm rối loạn trình biên dịch: kiểu trả về từ 'std :: vector :: begin()' không phải là 'T *' (hoặc 'T const * '). Dường như trình biên dịch không thể phát hiện rằng trình lặp này không là gì ngoài một trình bao bọc mỏng trên một con trỏ. –