Почему замена 0.1f на 0 замедляет производительность в 10 раз?
Проблема:
Почему следующий участок кода:
const float x[16] = { 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8,
1.9, 2.0, 2.1, 2.2, 2.3, 2.4, 2.5, 2.6};
const float z[16] = {1.123, 1.234, 1.345, 156.467, 1.578, 1.689, 1.790, 1.812,
1.923, 2.034, 2.145, 2.256, 2.367, 2.478, 2.589, 2.690};
float y[16];
for (int i = 0; i < 16; i++)
{
y[i] = x[i];
}
for (int j = 0; j < 9000000; j++)
{
for (int i = 0; i < 16; i++)
{
y[i] *= x[i];
y[i] /= z[i];
y[i] = y[i] + 0.1f; // <--
y[i] = y[i] - 0.1f; // <--
}
}
работает более чем в 10 раз быстрее, чем следующий (идентичный, за исключением отмеченных мест):
const float x[16] = { 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8,
1.9, 2.0, 2.1, 2.2, 2.3, 2.4, 2.5, 2.6};
const float z[16] = {1.123, 1.234, 1.345, 156.467, 1.578, 1.689, 1.790, 1.812,
1.923, 2.034, 2.145, 2.256, 2.367, 2.478, 2.589, 2.690};
float y[16];
for (int i = 0; i < 16; i++)
{
y[i] = x[i];
}
for (int j = 0; j < 9000000; j++)
{
for (int i = 0; i < 16; i++)
{
y[i] *= x[i];
y[i] /= z[i];
y[i] = y[i] + 0; // <--
y[i] = y[i] - 0; // <--
}
}
Я компилировал код с помощью Visual Studio 2010 SP1. Уровень оптимизации был установлен на -O2
, а sse2
включен. Другие компиляторы не были протестированы.
2 ответ(ов)
В GCC вы можете включить FTZ (Flush-to-Zero) и DAZ (Denormals Are Zero) следующим образом:
#include <xmmintrin.h>
#define FTZ 1
#define DAZ 1
void enableFtzDaz()
{
int mxcsr = _mm_getcsr ();
if (FTZ) {
mxcsr |= (1<<15) | (1<<11);
}
if (DAZ) {
mxcsr |= (1<<6);
}
_mm_setcsr (mxcsr);
}
Также не забудьте использовать флаги компиляции GCC: -msse -mfpmath=sse
.
Соответствующие заслуги принадлежат Карлу Хетерингтону [1].
Обновление на 2023 год. На Ryzen 3990X с gcc 10.2 и опциями компиляции -O3 -mavx2 -march=native
разница между двумя версиями составляет:
0.0f: 0.218s
0.1f: 0.127s
Таким образом, производительность все еще ниже, но разница уже не такая значительная, как 10 раз.
Является ли < быстрее, чем <=?
push_back против emplace_back: в чем разница?
Что такое "кэш-дружественный" код?
Как изменить цвет вывода echo в Linux
Разница между const int*, const int * const и int * const?