16

Почему замена 0.1f на 0 замедляет производительность в 10 раз?

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 ответ(ов)

0

В 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].

[1] http://carlh.net/plugins/denormals.php

0

Обновление на 2023 год. На Ryzen 3990X с gcc 10.2 и опциями компиляции -O3 -mavx2 -march=native разница между двумя версиями составляет:

0.0f: 0.218s
0.1f: 0.127s

Таким образом, производительность все еще ниже, но разница уже не такая значительная, как 10 раз.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь