Кто-нибудь видит что-то очевидное в коде цикла ниже, что я не вижу, почему это невозможно авто-векторизовать компилятором VS2012 С++?
Весь компилятор дает мне info C5002: loop not vectorized due to reason '1200'
, когда я использую ключ командной строки /Qvec-report:2
.
Причина 1200 задокументирована в MSDN как:
Loop содержит зависящие от цикла данные, которые предотвращают векторизации. Различные итерации петли мешают каждому другие такие, что векторизация цикла приведет к неправильным ответам и автоинтервализатор не может доказать себе, что таких данных нет зависимости.
Я знаю (или я уверен, что) нет зависимостей данных, связанных с циклом, но я не уверен, что мешает компилятору реализовать это.
Эти указатели source
и dest
никогда не перекрываются и не имеют одинаковой памяти, и я пытаюсь предоставить компилятору этот подсказку через __restrict
.
pitch
всегда является положительным целочисленным значением, что-то вроде 4096
, в зависимости от разрешения экрана, поскольку это функция рендеринга/преобразования 8bpp- > 32bpp, работающая по столбцу.
byte * __restrict source;
DWORD * __restrict dest;
int pitch;
for (int i = 0; i < count; ++i) {
dest[(i*2*pitch)+0] = (source[(i*8)+0]);
dest[(i*2*pitch)+1] = (source[(i*8)+1]);
dest[(i*2*pitch)+2] = (source[(i*8)+2]);
dest[(i*2*pitch)+3] = (source[(i*8)+3]);
dest[((i*2+1)*pitch)+0] = (source[(i*8)+4]);
dest[((i*2+1)*pitch)+1] = (source[(i*8)+5]);
dest[((i*2+1)*pitch)+2] = (source[(i*8)+6]);
dest[((i*2+1)*pitch)+3] = (source[(i*8)+7]);
}
Параны вокруг каждого source[]
- это остатки вызова функции, который я упустил здесь, потому что цикл по-прежнему не будет автоматически сгенерирован без вызова функции в самой простейшей форме.
EDIT:
Я упростил цикл до его самой тривиальной формы, которую я могу:
for (int i = 0; i < 200; ++i) {
dest[(i*2*4096)+0] = (source[(i*8)+0]);
}
Это все равно дает тот же код причины 1200.
РЕДАКТИРОВАТЬ (2):
Этот минимальный тестовый сценарий с локальными распределениями и идентичными типами указателей по-прежнему не может автоматически зацикливаться. В этот момент я просто озадачен.
const byte * __restrict source;
byte * __restrict dest;
source = (const byte * __restrict ) new byte[1600];
dest = (byte * __restrict ) new byte[1600];
for (int i = 0; i < 200; ++i) {
dest[(i*2*4096)+0] = (source[(i*8)+0]);
}