2014-11-15 13 views
10

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); 
+1

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

+0

@ 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

+3

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ỏ. –

Trả lời

1

Tôi đoán có thể là phạm vi có trụ sở tại vòng không ăn nói lấc cấc biết rằng đối tượng là một vector hoặc một mảng hoặc một danh sách liên kết do đó người khiếu nại không biết trước vectorizes vòng lặp. Phạm vi dựa trên các vòng lặp tương đương với vòng lặp foreach bằng các ngôn ngữ khác. Có thể có một cách để gợi ý trình duyệt để gợi ý trước khi vector hóa vòng lặp bằng cách sử dụng macro hoặc pragma hoặc cài đặt trình biên dịch. Để kiểm tra, hãy thử sử dụng mã trong các trình duyệt khác và xem những gì bạn nhận được, tôi sẽ không ngạc nhiên nếu bạn nhận được mã assembly không được vector hóa với các trình duyệt khác.

+0

bạn đã kiểm tra mã trên các trình duyệt khác và kiểm tra kết quả chưa? –

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