你有一个三(或四)个浮点数的向量.总结它们的最快方法是什么?
SSE(movaps,shuffle,add,movd)总是比x87快吗?SSE4.2中的水平加法说明值得吗?移动到FPU的成本是多少,然后是faddp,faddp?什么是最快的特定指令序列?
"尝试安排事情,这样你可以一次总结四个向量"将不被接受作为答案.:-)
我是指令优化的新手.
我对一个简单的函数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 …
我正在寻找一种更快,更棘手的方法来将C中的两个4x4矩阵相乘.我目前的研究主要集中在具有SIMD扩展的x86-64汇编上.到目前为止,我已经创建了一个函数,比一个简单的C实现快6倍,这超出了我对性能改进的期望.不幸的是,只有在没有使用优化标志进行编译时(GCC 4.7),这种情况才会成立.随着-O2,C变得更快,我的努力变得毫无意义.
我知道现代编译器利用复杂的优化技术来实现几乎完美的代码,通常比巧妙的手工装配更快.但在少数性能关键的情况下,人类可能会尝试使用编译器争取时钟周期.特别是,当一些支持现代ISA的数学可以被探索时(就像我的情况一样).
我的函数如下(AT&T语法,GNU汇编程序):
.text
.globl matrixMultiplyASM
.type matrixMultiplyASM, @function
matrixMultiplyASM:
movaps (%rdi), %xmm0 # fetch the first matrix (use four registers)
movaps 16(%rdi), %xmm1
movaps 32(%rdi), %xmm2
movaps 48(%rdi), %xmm3
xorq %rcx, %rcx # reset (forward) loop iterator
.ROW:
movss (%rsi), %xmm4 # Compute four values (one row) in parallel:
shufps $0x0, %xmm4, %xmm4 # 4x 4FP mul's, 3x 4FP add's 6x mov's per row,
mulps %xmm0, %xmm4 # expressed in four sequences of 5 instructions,
movaps …Run Code Online (Sandbox Code Playgroud)