Является ли предпочтение SIMD всегда избавляться от ветвления?

Если вы пишете какой-то SIMD-код, который будет выполняться другой программой, всегда ли выгодно избавиться от ветвления для повышения производительности? Я слышал, что даже выполнение дополнительных операций только для того, чтобы избежать операторов if/else и т. д., все равно намного быстрее.

Я спрашиваю об этом, потому что у меня есть несколько ответвлений, которые я делаю в основном так:

//  axis; x=0, y=1, z=2

float p, q;
if (axis == 0)
{
    p = point.y;
    q = point.z;
}
else if (axis == 1)
{
    p = point.x;
    q = point.z;
}
else if (axis == 2)
{
    p = point.x;
    q = point.y;
}

Могу ли я избежать такого ветвления с помощью какого-нибудь хитрого трюка?


person Joan Venge    schedule 17.01.2012    source источник
comment
Это действительно зависит от того, предсказуемы ли ветки или нет. Если вы вызываете эту функцию много раз подряд с одним и тем же значением оси, то лучше так. Если axis выглядит случайным, то стоит их оптимизировать. Если вы можете встроить его в код, который устанавливает axis, тогда это не будет иметь значения, поскольку вы все равно не получите ветки.   -  person David Schwartz    schedule 18.01.2012
comment
Спасибо, ось исправлена ​​на все звонки. Также под встраиванием вы подразумеваете просто встраивание соответствующей ветки? Если да, то это было бы мило. Я проверю, делает ли это компилятор.   -  person Joan Venge    schedule 18.01.2012
comment
Если эта функция встраивается, то сгенерированный код должен иметь только взятую ветвь. Если эта функция слишком велика для встраивания, вы можете сделать версию функции для каждого значения оси (только с этой ветвью), а затем иметь функцию «оболочки», которая делает встроенную, которая выбирает соответствующую невстроенную функцию на основе на значение axis. Встроенная оболочка должна исключить ветвь и вызвать правильную функцию без ветвей.   -  person David Schwartz    schedule 18.01.2012
comment
Также это на самом деле в основной функции, а не в отдельной функции. Имеет ли значение, выделю ли я его в другую функцию или оставлю в основной функции? Я думал, что он не слишком большой или общий и очень связан с основной функцией, так как больше ничего этого не использует.   -  person Joan Venge    schedule 18.01.2012


Ответы (1)


Большинство архитектур SIMD имеют специальные инструкции, которые позволяют вам условно выбирать элементы на основе вектора маски. Вектор маски обычно является результатом инструкции сравнения SIMD. Так что да, довольно легко избавиться от ветвей, которые есть в вашем примере выше.

Действительно ли вам нужно избавиться от той или иной ветки, будет зависеть от различных факторов, таких как предсказуемость ветки, характер (статистика) данных и объем кода, выполняемого условно. Как правило, бесветвевой доступ — это хорошо, но, как и в большинстве правил, есть исключения.

person Paul R    schedule 17.01.2012
comment
Спасибо, на самом деле программа вызывает мою функцию, зная, что значение фиксировано, но если я захочу, я могу сделать его динамическим в программе, но даже тогда программа будет знать, что значение не совпадает с тем, которое вызывает мою функцию. Я не уверен, что он использует эту информацию. Будет ли печатать что-то в ветвях и смотреть, печатается ли оно один раз или для каждого объекта/элемента, доказывает, что компилятор действительно оптимизирует это? - person Joan Venge; 18.01.2012
comment
Трудно дать конкретный совет, не зная, какой процессор, компилятор и т. д. вы используете. Обычно вы хотите просмотреть сгенерированный код (например, gcc -S) и/или использовать профилировщик для выявления узких мест в производительности. - person Paul R; 18.01.2012