2013-06-26 3 views
1

Я работаю над кодовой базой, которая имеет много встроенного кода SIMD. Теперь, когда у нас есть AVX2, нам все еще нужно иметь код SIMD, который работает на процессорах, не поддерживающих AVX2, что значительно улучшит работу. Кроме того, эти ограничения на пропускную способность в 128 бит для перетасовки AVX2 также усложняют ситуацию. По этим причинам, самое время больше полагаться на автоматическую вектологию. Главные вещи, которые меня пугают, - это перспектива единственного невинного изменения, убивающего параллелизм и перспективы отладки автоиндексированного кода в случае возникновения проблемы.Вы можете отлаживать автоматические векторизованные циклы?

я составил следующий с г ++ -O1 -g -ftree-Vectorize и попытался пройти через с помощью GDB (кто-нибудь знает, почему -ftree-векторизовать не работает с -O0?)

float a[1000], b[1000], c[1000]; 
int main(int argc, char **argv) 
{ 
    for (int i = 0; i < argc; ++i) 
    c[i] = a[i] + b[i]; 
    return 0; 
} 

, но не получают каких-либо значимых результатов. Например, иногда значение для i говорит о том, что значение < оптимизировано вне >, а в других случаях оно перескакивает на 20.

Похоже, основная проблема заключается в том, что сложно отобразить состояние SIMD в исходное состояние C для отладки. Но реалистично, можно ли это сделать?

+0

Почему вы хотите отладить его? Если вы хотите проверить, что он векторизован, не лучше ли, проверить код сборки или запустить тесты (при полных настройках оптимизации)? Если вы хотите найти ошибку, отлаживайте не-векторизованную (и в противном случае не оптимизированную) версию. – delnan

+0

Да, ошибки компилятора неприятны, когда и если они случаются. Я не знаю, является ли отладчик (исходный уровень) подходящим инструментом для его поиска, но в любом случае я понимаю. – delnan

+0

Итак, отладка для ошибок в основном гипотетическая.Я определенно помню, как вы отправили ошибку в векторизаторе Visual C++ 2010, из-за которой он неправильно сливал невыровненную нагрузку с арифметической инструкцией в одну инструкцию x86, в результате чего она вылетала при запуске в не выровненном массиве. –

ответ

0

Использование отладчика по автоиндексированному коду сложно, особенно. когда вы хотите проверить переменные, которые должны вести себя по-разному (например, счетчик циклов).

Вы можете использовать отладочную сборку (-O0 или -Og), или вы можете понять, как компилятор векторизовал код и изучает регистры asm и регистры. В зависимости от того, какую ошибку вы должны отслеживать, у вас может возникнуть или не возникнет проблема с авто-векторизованной сборкой.

Это звучит из комментариев, так как вы больше заинтересованы в проверке эффективности автоматической векторизации, а не на самом деле отладке, чтобы исправить логические ошибки в вашем коде. Глядя на asm и контрольные показатели, вероятно, ваш лучший выбор. (даже простой rdtsc до/после вызова или в модульном тесте, который также проверяет производительность, а также правильность.)

Иногда компилятор генерирует несколько версий цикла, например. для случая, когда входные массивы перекрываются, а для случая, когда они этого не делают. Одношаговый (по инструкции, с stepi, с layout asm в gdb) может помочь, пока вы не найдете цикл, который фактически выполняет большую часть работы. Затем вы можете сосредоточиться на том, как он векторизован. Если вы хотите исключить проверки и альтернативные версии, то могут быть полезны указатели restrict. Также есть p = __builtin_assume_aligned(p, 16).

Вы также можете использовать Intel's free code analyzer, чтобы попытаться статически проанализировать, сколько циклов занимает итерация. Поместите метки IACA в верхнюю часть вашего тела цикла и после закрытия паттерна вашего цикла, и надеемся, что GCC помещает их в соответствующие места в автоинъектизированном цикле и что встроенный asm не прерывает автоматическое векторизация.

Ответы на оптимизацию не будут содержать ссылку на http://agner.org/optimize/, поэтому здесь вы идете.

Смежные вопросы