26.11.2015

SSE

Начал пытаться оптимизировать под SSE wavelet-преобразование.

Чисто теоретически система команд SIMD позволяет одновременно выполнить сразу несколько команд (4 в случае SSE). Правда, за это приходится платить тем, что данные для таких команд надо подготовить. Ситуации, когда данные расположены не подряд в памяти, не так уж редки. В наборе команд SSE1 (самой первой версии), специальных инструкций для таких случаев я не обнаружил.

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

С тех пор утекло много воды. Сейчас все процессоры имеют конвейерную и суперскалярную архитектуру даже для обычных команд. А вот для векторных, похоже, все осталось, как во времена CRAY. Сейчас обычные, но независимые команды могут выполнятся параллельно. И, такое ощущение, что векторные регистры не имеют никакого преимущества по сравнению с обычными командами, если обычные команды удастся распараллелить.

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

Для выполнения вейвлет-преобразования необходимо выполнить векторное произведение. Если его написать тупо, вот так например:

result := 0;
for i := 0 to 3 do
  result := result+v1[i]*v2[i]

то особо параллельного выполнения команд здесь не будет. А вот если переписать в таком виде

result := v1[0]*v2[0]+v1[1]*v2[1]+v1[2]*v2[2]+v1[3]*v2[3]

то тут есть где разгуляться современному процессору.

Ну так вот. Такой код при включенной оптимизации работает лишь чуть медленнее варианта на  ассемблере под SSE1. Это показалось мне подозрительным и я переписал исходный скалярный код с паскаля на ассемблер. Вуаля: это код работает чуть быстрее, чем SSE1.

Хотя, может это просто мой процессор дешевый и модуль SSE у него не быстрый? Еще одна тема вызывает у меня удивление: это набор команд SSE. Наверное, я чего-то не понимаю, но мне они показались чрезвычайно неудобными.

Теперь продолжу эксперименты с более новыми версиями SSE, там в версии 4 есть даже вариант, который, собственно, считает векторное произведение. Может, это существенно ускорит работу SIMD.

Комментариев нет:

Отправить комментарий