умножение с плавающей запятой на sse2 - PullRequest
3 голосов
/ 27 марта 2012

Я попытался перенести код из FANN Lib (нейронная сеть, написанная на C) на SSE2. Но производительность SSE2 ухудшилась по сравнению с обычным кодом. В моей реализации SSE2 один запуск занимает 5,50 мин без 5,20 мин.

Как SSE2 может работать медленнее, чем обычный? Может ли это быть из-за _mm_set_ps? Я использую компилятор Apple LLVM (XCode 4) для компиляции кода (все флаги расширения SSE включены, уровень оптимизации -Os).

Код без SSE2

                neuron_sum +=
                fann_mult(weights[i], neurons[i].value) +
                fann_mult(weights[i + 1], neurons[i + 1].value) +
                fann_mult(weights[i + 2], neurons[i + 2].value) +
                fann_mult(weights[i + 3], neurons[i + 3].value);

код SSE2

                __m128 a_line=_mm_loadu_ps(&weights[i]);
                __m128 b_line=_mm_set_ps(neurons[i+3].value,neurons[i+2].value,neurons[i+1].value,neurons[i].value);
                __m128 c_line=_mm_mul_ps(a_line, b_line);
                neuron_sum+=c_line[0]+c_line[1]+c_line[2]+c_line[3];

1 Ответ

5 голосов
/ 27 марта 2012

Чтобы иметь шанс увидеть ускорение здесь, вам нужно сделать следующее:

  • убедитесь, что weights[i] выровнен на 16 байт, а затем используйте _mm_load_ps вместо _mm_loadu_ps
  • реорганизовать neurons[] так, чтобы это был SoA вместо AoS (и также выровненный по 16 байтам), а затем использовать _mm_load_ps для загрузки 4 значений одновременно
  • вывести горизонтальную сумму из цикла (есть цикл, верно?) - просто сохраните 4 частичные суммы в векторе vneurom_sum и затем сделайте одну окончательную горизонтальную сумму для этого вектора после цикла

Даже в этом случае вы не увидите значительного ускорения, поскольку вы выполняете только одну арифметическую операцию для 2 нагрузок и 1 магазина. Поскольку большинство современных процессоров x86 имеют два скалярных FPU, в любом случае, вы, вероятно, не приблизитесь к теоретическому 4-кратному ускорению для 128-разрядной SIMD-карты с плавающей запятой, я бы ожидал, что, по меньшей мере, 50-процентное ускорение относительно скалярного кода *. 1017 *

...