В следующей строке:
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
Первым вариантом может быть беспроигрышное решение (без прогноза ветвлений, лучшая производительность).
Процессоры выполняют регулярное умножение с 0
с и 1
s.
Причина в том, что если процессор будет проверять 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
Других решений пока нет …