Перед заменой большого количества моих "старых" циклов на циклы диапазона, основанных на циклах, я провел несколько тестов с visual studio 2013:
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);
глядя на разборку, все векторы были обозначены стандартом:
00BFE9B0 vpaddd xmm1,xmm1,xmmword ptr [eax]
00BFE9B4 add ecx,4
00BFE9B7 add eax,10h
00BFE9BA cmp ecx,edx
00BFE9BC jne main+140h (0BFE9B0h)
но диапазон, основанный на циклах, не был:
00BFEAC6 add esi,dword ptr [eax]
00BFEAC8 lea eax,[eax+4]
00BFEACB inc ecx
00BFEACC cmp ecx,edi
00BFEACE jne main+256h (0BFEAC6h)
Есть ли причина, по которой компилятор не мог векторизовать эти циклы?
Я действительно хотел бы использовать новый синтаксис, но потерять векторию слишком плохо.
Я только что увидел этот вопрос, поэтому я попробовал флаг /Qvec-report:2
, указав еще одну причину:
loop not vectorized due to reason '1200'
то есть:
Loop содержит зависящие от цикла данные, которые предотвращают векторизация. Различные итерации петля мешает друг другу, так что векторизация цикла приведет к неправильным ответам и автоинтервализатор не может доказать себе, что таких данных не существует.
Это же ошибка? (Я также пробовал с последним компилятором vС++ "C 2013" )
Должен ли я сообщать об этом также на MS connect?
Изменить
Du для комментариев, я сделал тот же тест с сырым массивом int вместо вектора, поэтому не задействован класс итератора, а только сырые указатели.
Теперь все циклы векторизованы, за исключением двух "симулированных диапазонов".
Компилятор говорит, что это связано с причиной "501":
Индукционная переменная не является локальной; или верхняя граница не является петлевой инвариантной.
Я не понимаю, что происходит...
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);