我是指令优化的新手.
我对一个简单的函数dotp进行了简单的分析,该函数用于获取两个浮点数组的点积.
C代码如下:
float dotp(
const float x[],
const float y[],
const short n
)
{
short i;
float suma;
suma = 0.0f;
for(i=0; i<n; i++)
{
suma += x[i] * y[i];
}
return suma;
}
Run Code Online (Sandbox Code Playgroud)
我用昂纳雾在网络上提供的测试框架testp.
在这种情况下使用的数组是对齐的:
int n = 2048;
float* z2 = (float*)_mm_malloc(sizeof(float)*n, 64);
char *mem = (char*)_mm_malloc(1<<18,4096);
char *a = mem;
char *b = a+n*sizeof(float);
char *c = b+n*sizeof(float);
float *x = (float*)a;
float *y = (float*)b;
float *z = (float*)c;
Run Code Online (Sandbox Code Playgroud)
然后我调用函数dotp,n = 2048,repeat …
我正在阅读这本书:"计算机系统 - 程序员视角".我发现,在x86-64架构中,我们仅限于6个积分参数,这些参数将被传递给寄存器中的函数.下一个参数将在堆栈上传递.
而且,第一个最多8个FP或矢量args以xmm0..7传递.
为什么不使用浮点寄存器来存储下一个参数,即使参数不是单/双精度变量?
将数据存储在寄存器中比将其存储到存储器然后从存储器中读取它会更有效(据我所知).
大多数架构都有不同的寄存器组来存储常规整数和浮点数。从二进制存储的角度来看,东西存储在哪里应该不重要吧?只是 1 和 0,他们不能将相同的通用寄存器通过管道传输到浮点 ALU 中吗?
SIMD(xmmx64 中)寄存器能够存储浮点和常规整数,那么为什么相同的概念不适用于常规寄存器呢?
据我了解,浮点存储在XMM寄存器中,而不是诸如的通用寄存器中eax,因此我做了一个实验:
float a = 5;
Run Code Online (Sandbox Code Playgroud)
在这种情况下,a被存储1084227584在XMM寄存器中。这是程序集版本:
.text
.global _start
.LCO:
.long 1084227584
_start:
mov .LCO, %eax
movss .LCO, %xmm0
Run Code Online (Sandbox Code Playgroud)
执行上述组件和使用它的调试gdb显示,在值eax将是1084227584,然而,在值ymm0是5。
这是我的问题:
1- XMM寄存器有什么特别之处?除了SIMD指令,它们是唯一存储浮点的寄存器类型吗?
为什么不能在常规寄存器中设置相同的位?
2- float和double值始终存储为浮点吗?
我们永远不能将它们存储为fixed pointC或汇编语言吗?