Действительно ли процессоры вычисляют умножение на ноль или единицу? Зачем?

В следующей строке:

aData[i] = aData[i] + ( aOn * sin( i ) );

Если aOn является 0 или же 1действительно ли процессор выполняет умножение, или он условно вычисляет результат (0 за 0, другое значение для 1)?

Я смотрю на согласованность производительности алгоритма, который частично включает в себя изучение эффекта Прогнозирование отрасли.

Гипотеза заключается в том, что этот код:

for ( i = 0; i < iNumSamples; i++ )
aData[i] = aData[i] + ( aOn * sin( i ) );

обеспечит более стабильную производительность, чем этот код (где предсказание ветвления может дестабилизировать производительность):

for ( i = 0; i < iNumSamples; i++ )
{
if ( aOn )
aData[i] = aData[i] + sin( i );
}

с aOn быть либо 0 или же 1и может переключаться во время выполнения цикла другим потоком.

Фактический условный расчет (+ sin( i ) в приведенном выше примере) включает в себя больше обработки, и условие if должно быть в цикле (существует множество условий, а не только одно, как в примере выше; также изменяется aOn должен иметь эффект немедленно, а не за цикл).

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

Несмотря на это, легко заметить, что если процессор не будет выполнять фактическое умножение для таких значений, как 1 а также 0Первым вариантом может быть беспроигрышное решение (без прогноза ветвлений, лучшая производительность).

7

Решение

Процессоры выполняют регулярное умножение с 0с и 1s.

Причина в том, что если процессор будет проверять 0 а также 1 перед каждым расчетом введение условия займет больше циклов. В то время как вы получите производительность для 0 а также 1 множители, вы потеряете производительность для любых других значений (которые гораздо более вероятны).

Простая программа может доказать это:

#include <iostream>
#include "cycle.h"#include "time.h"
void Loop( float aCoefficient )
{
float iSum = 0.0f;

clock_t iStart, iEnd;

iStart = clock();
for ( int i = 0; i < 100000000; i++ )
{
iSum += aCoefficient * rand();
}
iEnd = clock();
printf("Coefficient: %f: %li clock ticks\n", aCoefficient, iEnd - iStart );
}

int main(int argc, const char * argv[])
{
Loop( 0.0f );
Loop( 1.0f );
Loop( 0.25f );

return 0;
}

Для которого вывод:

Coefficient: 0.000000: 1380620 clock ticks
Coefficient: 1.000000: 1375345 clock ticks
Coefficient: 0.250000: 1374483 clock ticks
6

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]