Время выполнения с плавающей запятой - PullRequest
4 голосов
/ 12 января 2010

Что объясняет добавленное время выполнения первого набора данных? Инструкции по сборке одинаковы.

Если флаг DN_FLUSH не включен, первый набор данных занимает 63 миллисекунды, второй набор занимает 15 миллисекунд.
При установленном флаге DN_FLUSH первый набор данных занимает 15 миллисекунд, второй набор занимает ~ 0 миллисекунд.

Следовательно, в обоих случаях время выполнения первого набора данных намного больше.

Есть ли способ уменьшить время выполнения, чтобы оно было ближе к второму набору данных?

Я использую C ++ Visual Studio 2005, / arch: SSE2 / fp: быстро работает на Intel Core 2 Duo T7700 @ 2,4 ГГц Windows XP Pro.

#define NUMLOOPS 1000000

// Denormal values flushed to zero by hardware on ALPHA and x86
// processors with SSE2 support. Ignored on other x86 platforms
// Setting this decreases execution time from 63 milliseconds to 16 millisecond
// _controlfp(_DN_FLUSH, _MCW_DN);

float denormal = 1.0e-38;
float denormalTwo = 1.0e-39;
float denormalThree = 1;

tickStart = GetTickCount();

// Run First Calculation Loop 
for (loops=0; loops < NUMLOOPS; loops++)
{
    denormalThree = denormal - denormalTwo;
}

// Get execution time
duration = GetTickCount()-tickStart;
printf("Duration = %dms\n", duration);

float normal = 1.0e-10;
float normalTwo = 1.0e-2;
float normalThree = 1;

tickStart = GetTickCount();

// Run Second Calculation Loop 
for (loops=0; loops < NUMLOOPS; loops++)
{
    normalThree = normal - normalTwo;
}

// Get execution time
duration = GetTickCount()-tickStart;
printf("Duration = %dms\n", duration);

Ответы [ 2 ]

11 голосов
/ 12 января 2010

Цитирование из руководства по оптимизации Intel:

Когда входной операнд для SIMD инструкция с плавающей точкой [здесь это включает в себя скалярную арифметику, выполненную с использованием SSE] содержит значения, которые меньше, чем представимый диапазон типа данных, происходит ненормальное исключение. это вызывает значительную производительность штраф. SIMD с плавающей точкой операция имеет режим сброса в ноль в результаты которого не будут занижены. Поэтому последующие вычисления не грозит штраф за исполнение обработка операндов ненормального ввода.

Что касается того, как этого избежать, если вы не можете сбросить денормалы: сделайте все возможное, чтобы убедиться, что ваши данные масштабируются надлежащим образом, и вы не столкнетесь с денормалями в первую очередь. Обычно это означает задержку применения некоторого масштабного коэффициента до тех пор, пока вы не закончите все остальные вычисления.

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

2 голосов
/ 12 января 2010

Еще одна цитата из руководств Intel, том 1, глава 10.2.3.3:

Режим сброса в ноль не совместим со стандартом IEEE 754. IEEE уполномочен замаскированный ответ на недополнение должен дать денормализованный результат (см. Раздел 4.8.3.2, «Нормализованные и денормализованные конечные числа»). Флеш-ноль Режим предоставляется в основном по причинам производительности . За счет небольшой точности потери, более быстрое выполнение может быть достигнуто для приложений, где частые потери и допустимо округление результата занижения до нуля.

...