INTEL SIMD: почему умножение на месте происходит так медленно? - PullRequest
0 голосов
/ 27 ноября 2018

Я написал несколько векторных методов, которые выполняют простую математику на месте или копируют и имеют одинаковое наказание для варианта на месте.

Самое простое можно свести к следующему:

void scale(float* dst, const float* src, int count, float factor)
{
    __m128 factorV = _mm_set1_ps(factorV);

    for(int i = 0; i < count; i+= 4)
    {
        __m128 in = _mm_load_ps(src);
        in = _mm_mul_ps(in, factorV);
        _mm_store_ps(dst, in);

        dst += 4;
        src += 4;
    }
}

код тестирования:

for(int i = 0; i < 1000000; i++)
{
    scale(alignedMemPtrDst, alignedMemPtrSrc, 256, randomFloatAbsRange1);
}

При тестировании, т. Е. Многократном использовании этой функции в тех же буферахЯ обнаружил, что если dst и src одинаковы, скорость одинакова.Если они разные, это примерно в 70 раз быстрее.Основные циклы, записанные при записи (т. Е. _Mm_store_ps)

Интересно, что такое же поведение не выполняется для сложения, то есть + = работает хорошо, только * = это проблема ..

-

На это ответили в комментариях.Это ненормально во время искусственного тестирования.

1 Ответ

0 голосов
/ 28 ноября 2018

Ваш factor дает ненормальный результат?Не ноль, но меньше, чем FLT_MIN?Если за пределами этого есть цикл, который повторяет один и тот же блок на месте, числа могут стать достаточно маленькими, чтобы требовать медленных передач FP .

( Оказывается, да это была проблема для OP).

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

Для получения результата +-Inf или NaN не требуется дополнительного времени, но для постепенного уменьшения значенияпо крайней мере на процессорах Intel по крайней мере.Это одна из причин, по которой -ffast-math устанавливает DAZ / FTZ - сбрасывание в ноль при недостаточном потоке.


Мне кажется, я читал, что у AMD нет микрокодированной обработки субнормалей с помощью FP, но Intelделает.

На процессорах Intel есть счетчик производительности для fp_assist.any, который подсчитывает, когда для ненормального результата требуются дополнительные микрокоды для обработки специального случая.(Я думаю, что это так же навязчиво, как и для внешнего интерфейса и исполнительного директора. Однако это определенно медленно.)


Почему денормализованные операции с плавающей точкой намного медленнее, чем у других операций с аппаратной архитектуройviewpoint?

Почему icc генерирует странную сборку для простого главного? (показывает, как ICC устанавливает FTZ / DAZ в начале main, по умолчанию это fast-mathустановка.)

...