simd寄存器的大小端问题
SIMD寄存器的数据存储模式
一直很疑惑,SIMD寄存器中数据以什么形式进行存储的。首先简单介绍一下大小端:我们用地址最低位来表示程序的一个object,无论这个object是一个整数、数组、class、或者其他数据结构。我们表示这个object,用的一直是地址最低位。当我们知道了object的大小,我们变知道了这个object全部字节。问题就是,我们如何解释这些字节?
大小端这个这个概念其实从我接触计算机的时候就一直困惑着我,包括后来考研也没有把这块给弄清楚。
-
内存地址从高地址往低地址进行生长。数据无论是c++中class还是array都是一串比特流,是从低地址一直放到高地址。
-
任何object的地址,比如c++中的class或者数组都可以被视为一个object。而最低的地址用于表示object的起始地址。
-
数组有些特殊:
例如
short a[] = {1, 2, 3},那么从低位到高位进行存放bit,0x010002000300。数组是按index从低地址放到高地址,数组中元素是按照byte从低地址放到高地址,这看起来有点奇怪。但是记住这张图就行了

我自己也做了一些试验:

可以看到bit是翻转的。
-
普通寄存器中的endian。按道理寄存器中是没有endian的概念了,但因为x86-64同时保留了
rax与eax这些概念。导致我们访问一个64位的寄存器,实际上是一个big endian的顺序。比如数字0x00000001,存放在eax中,那么有效位1实际上在ax中也能看到。寄存器的字节序就是数字的表示顺序。 -
simd寄存器。在上面提到寄存器中实际上是大端,但是simd寄存器,例如
xmmm0,它可以存放4个float数值。如果我们使用_mm_set_ps(1.0, 2.0, 3.0, 4.0),其寄存器中的组织和内存的字节序如下图:
如果我们通过代码来看的话,我们可以看到,结果和我们的预期一样:

- simd中bit的index如何定义?例如hadd这个simd函数
simd寄存器中哪一端是128哪一端是0?实际通过代码实验我们确定了simd的index顺序,我们以load_ss这个函数为例子验证了我们的猜测

至此,我们彻底搞明白了寄存器的右端是index 0。大小端这个困惑了我多年的问题至此圆满解决,✿✿ヽ(°▽°)ノ✿

浙公网安备 33010602011771号