Для чего используются регистры от 128 до 512 бит? - PullRequest
0 голосов
/ 22 октября 2018

Посмотрев таблицу регистров в архитектуре x86 / x64, я заметил, что существует целый раздел из 128, 256 и 512-битных регистров, которые я никогда не видел, чтобы они использовались в сборке или декомпилированной C /Код C ++: XMM (0-15) для 128, YMM (0-15) для 256, ZMM (0-31) 512.

После небольшого копания я понял, что у вас естьиспользовать 2 64-битные операции для выполнения математических операций над 128-битным числом, вместо использования общих операций add, sub, mul, div.Если это так, то зачем использовать эти расширенные наборы регистров, и есть ли какие-либо операции сборки, которые вы можете использовать для манипулирования ими?

Ответы [ 2 ]

0 голосов
/ 22 октября 2018

Они используются в

  • Операции с плавающей запятой
  • Операции с несколькими данными одновременно

вам нужно использовать 2 64битовые операции для выполнения математических операций над 128-битным числом

Нет, они не предназначены для этой цели, и их нельзя легко использовать для 128-битных чисел.Намного быстрее добавить 128-битное число только с двумя инструкциями: add rax, rbx; adc rdx, rcx вместо тонны инструкций при работе с регистрами XMM.См.


Что касается их использования, то во-первых, они используются для скалярных операций с плавающей точкой .Так что если у вас есть float или double в C или C ++, то они, скорее всего, будут храниться в нижней части регистров XMM и обрабатываться инструкциями, заканчивающимися на ss ( скалярное одиночное ) илиsd ( скалярное двойное )

На самом деле существует еще один набор из восьми 80-битных ST(x) регистров, который был доступен с сопроцессором x87 дляделать математику с плавающей точкой.Однако они медленные и менее предсказуемые.Медленно, потому что операции выполняются с высокой точностью по умолчанию, что по сути требует больше работы , а также требует сохранения, а затем загружает до округления для уменьшения точности при необходимости.Непредсказуемо также из-за высокой точности.Поначалу это может показаться странным, но это легко объяснить, например, переполнение или недополнение некоторых операций с точностью float или double, но не с точностью long double.Это приводит к множеству ошибок или неожиданным результатам в 32- и 64-битной сборке 1

Вот пример с плавающей запятой для обоих наборов регистров

// f = x/z + y*z
x87:
        fld     dword ptr [esp + 12]
        fld     st(0)
        fdivr   dword ptr [esp + 4]
        fxch    st(1)
        fmul    dword ptr [esp + 8]
        faddp   st(1)
        ret
SSE:
        divss   xmm0, xmm2
        mulss   xmm1, xmm2
        addss   xmm0, xmm1
        ret
AVX:
        vdivss  xmm0, xmm0, xmm2
        vmulss  xmm1, xmm1, xmm2
        vaddss  xmm0, xmm0, xmm1
        ret

Переход на более быстрые и согласованные регистры SSE является одной из причин, по которой тип 80-битной расширенной точности long double больше не доступен в MSVC


Затем Intel представила MMX набор команд для SIMD операций, который использует те же самые регистры ST(x) с новым именем MMX.MMX может означать Multiple Math eXtension или Matrix Math eXtension , но ИМХО это наиболее вероятно или MultiMedia eXtension , так как мультимедиа и Интернет приобретают все большее значение в то время,В мультимедийных решениях вам очень часто приходится выполнять одни и те же операции с каждым пикселем, текселем, сэмплом ... вот так

for (int i = 0; i < 100000; ++i)
{
   A[i] = B[i] + C[i];
   D[i] = E[i] * F[i];
}

Вместо того, чтобы работать с каждым элементом по отдельности, мы можем ускорить работу с помощью нескольких элементоввовремя.Вот почему люди изобрели SIMD.С MMX вы можете увеличить яркость 8-пиксельных каналов или громкость четырех 16-битных сэмплов одновременно ... Операции над одним элементом называются scalar , а полный регистр называется вектором,который представляет собой набор скалярных значений

Из-за недостатков MMX (таких как повторное использование ST регистров или отсутствие поддержки с плавающей запятой), когда расширенный набор инструкций SIMD установлен с помощью Потоковые расширения SIMD(SSE) Intel решила предоставить им совершенно новый набор регистров с именем XMM, который в два раза длиннее (128 бит), поэтому теперь мы можем работать с 16 байтами одновременно.И он также поддерживает несколько операций с плавающей точкой одновременно.Затем Intel удлинила XMM до 256-битного YMM в Advanced Vector Extensions (AVX) и еще раз удвоила длину в AVX-512 (на этот раз она также увеличила количество регистров).до 32 в 64-битном режиме).Теперь вы можете работать с шестнадцатью 32-битными целыми числами за один раз

Из вышесказанного вы можете понять вторую и наиболее важную роль этих регистров: выполнение операций над несколькими данными параллельно с одной инструкцией .Например, в SSE4 был представлен набор инструкций для работы со строками C .Теперь вы можете считать длину строки, находить подстроки ... намного быстрее, проверяя несколько байтов одновременно.Вы также можете копировать или сравнивать память намного быстрее.Современные реализации memcpy перемещают 16, 32 или 64 байта за раз, в зависимости от наибольшей ширины регистра, а не один за другим, как в простейшем решении C.

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

Ввиду важности SIMD, в настоящее время практически любая высокопроизводительная архитектура имеет собственную версию SIMD, такую ​​как Altivec на PowerPC или Neon на ARM.


1 Некоторые примеры:

0 голосов
/ 22 октября 2018

Эти регистры являются частью расширений набора команд SSE, AVX и AVX512.Ваш компилятор C должен, по крайней мере, использовать младшие 64-битные из них для операций с плавающей запятой, как это указано в ABI.

Эти регистры являются SIMD-регистрами (однонаправленные множественные данные), которые в основном используются для высокопроизводительного кода.Процессор поддерживает специальные инструкции SIMD, которые могут обрабатывать несколько данных одновременно, занимая столько времени, сколько обычно требуется для обработки одного элемента данных.Большая часть кода, использующего эти регистры, написана на ассемблере или с использованием специальных встроенных функций , потому что компиляторы довольно плохо используют инструкции SIMD самостоятельно.Улучшение компиляторов (оптимизация под названием auto vectorization ) является активной областью исследований.

В качестве примера, предположим, что программа хочет выполнить матричное умножение чисел с плавающей запятой двойной точности,С регистром AVX ymm0 до ymm15 можно обрабатывать 4 числа одновременно, что ускоряет алгоритм в 4 раза по сравнению с обычной реализацией.Это большая разница.

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

...