Есть ли соглашение для отображения/записи больших регистров, например, доступных в наборе инструкций Intel AVX?
Например, если у вас есть 1 наименее значимого байта и 20 в самом значительном байте и 0 в другом месте в регистре xmm
, для байт-мудрый дисплей является следующим предпочтительным (little-endian):
[1, 0, 0, 0, ..., 0, 20]
или является предпочтительным:
[20, 0, 0, 0, ..., 0, 1]
Аналогично, при отображении таких регистров, состоящих из более крупных элементов данных, применяется одно и то же правило? Например, чтобы отобразить регистр как DWORD, я предполагаю, что каждый DWORD все еще записан обычным (по-бинарному) образом, но каков порядок DWORDS:
[0x1, 0x0, ..., 0x14]
против
[0x14, 0x0, ..., 0x1]
Обсуждение
Я думаю, что два наиболее перспективных ответа - это просто "LSE 1 сначала" (т.е. первый вывод в приведенных выше примерах) или "MSE first" (второй вывод). Ни один из них не зависит от сущности платформы, так как действительно один раз в регистре данные, как правило, независимы от конца (например, операции в регистре GP или long
или int
или что-то другое в C не зависят от сущности). Endianness появляется в интерфейсе register ↔ памяти, и здесь я запрашиваю данные уже в регистре.
Возможно, существуют и другие ответы, такие как вывод, который зависит от сущности (и ответ Пол R может быть одним, но я не могу сказать).
LSE First
Одним из преимуществ LSE-first, по-видимому, является особенно байт-выход: часто байты нумеруются от 0 до N, при этом LSB равен нулю 2 поэтому вывод LSB-first выводит его с увеличением индексов, так же, как вы выведете массив байтов размера N.
Он также хорош в маленьких endian-архитектурах, поскольку выход затем соответствует представлению в памяти одного и того же вектора, хранящегося в памяти.
MSE First
Основным преимуществом здесь является то, что выход для более мелких элементов находится в том же порядке, что и для больших размеров (только с разной группировкой). Например, для 4-байтового вектора в нотации MSB [0x4, 0x3, 0x2, 0x1]
вывод для элементов байта, слова и элементов слова будет следующим:
[0x4, 0x3, 0x2, 0x1] [0x0403, 0x0201] [0x04030201]
По сути, даже с байтового вывода вы можете просто "считывать" слово или выход dword или наоборот, так как байты уже находятся в обычном MSB-первом порядке для отображения номера. С другой стороны, соответствующий вывод для LSE-first:
[0x1, 0x2, 0x3, 0x4] [0x0201, 0x0403] [0x04030201]
Обратите внимание, что каждый слой подвергается свопам относительно строки над ним, поэтому гораздо труднее считывать большие или меньшие значения. Вам нужно будет больше полагаться на вывод элемента, наиболее естественного для вашей проблемы.
Этот формат также имеет то преимущество, что на архитектуре BE выход затем соответствует представлению в памяти одного и того же вектора, хранящегося в памяти 3.
Intel сначала использует MSE в своих руководствах.
1 Наименее значимый элемент
2 Такие нумерации предназначены не только для целей документации - они являются архитектурно видимыми, например, в масках в случайном порядке.
3 Конечно, это преимущество крохотное по сравнению с соответствующим преимуществом LSE-первых на платформах LE, так как BE почти мертв в аппаратных средствах SIMD.