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从低地址放到高地址,这看起来有点奇怪。但是记住这张图就行了

image-20221207184939072

我自己也做了一些试验:

image-20221207183042583

可以看到bit是翻转的。

  • 普通寄存器中的endian。按道理寄存器中是没有endian的概念了,但因为x86-64同时保留了 raxeax这些概念。导致我们访问一个64位的寄存器,实际上是一个big endian的顺序。比如数字0x00000001,存放在eax中,那么有效位1实际上在 ax中也能看到。寄存器的字节序就是数字的表示顺序。

  • simd寄存器。在上面提到寄存器中实际上是大端,但是simd寄存器,例如xmmm0,它可以存放4个float数值。如果我们使用_mm_set_ps(1.0, 2.0, 3.0, 4.0),其寄存器中的组织和内存的字节序如下图:

    simd

    如果我们通过代码来看的话,我们可以看到,结果和我们的预期一样:

image-20221207190814898

  • simd中bit的index如何定义?例如hadd这个simd函数
image-20221207192307667

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

simd-index.drawio

image-20221207194355768 image-20221207194420320

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

posted @   kalice  阅读(186)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
历史上的今天:
2021-10-28 python 保存字典
点击右上角即可分享
微信分享提示