我是指令优化的新手.
我对一个简单的函数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 …
我正在尝试使用simd内部函数在C中编程矩阵乘法。我非常确定自己的实现,但是执行时,我会从所得矩阵系数的第5位开始出现一些数字错误。
REAL_T只是具有typedef的浮点数
/* This is my matmul Version with simd, using floating simple precision*/
void matmul(int n, REAL_T *A, REAL_T *B, REAL_T *C){
int i,j,k;
__m256 vA, vB, vC, vRes;
for (i=0; i<n; i++){
for (j=0; j<n; j++){
for (k=0; k<n; k= k+8){
vA = _mm256_load_ps(&A[i*n+k]);
vB = _mm256_loadu_ps(&B[k*n+j]);
vC = _mm256_mul_ps(vA, vB);
vC = _mm256_hadd_ps(vC, vC);
vC = _mm256_hadd_ps(vC, vC);
/*To get the resulting coefficient, after doing 2 hadds,
I have to get the first and the last element …Run Code Online (Sandbox Code Playgroud) 考虑数字的排序(升序)数组double。为了数值稳定,应该对数组求和,就好像从头到尾迭代一样,将总和累加到某个变量中。
如何使用AVX2有效地向量化?
我研究了此方法用AVX指令完成水平向量求和的最快方法,但是将其缩放为数组(可能需要一些分治法)似乎很棘手,同时通过确保小数来保持浮点精度在将它们添加到更大数量之前进行汇总。
澄清1:我认为应该可以将例如前4个项目相加,然后将它们添加到接下来4个项目的合计中,以此类推。但是我更喜欢一种不会完全破坏稳定性的方法。
澄清2:内存不应成为瓶颈,因为该阵列位于L3高速缓存中(但不应位于L1 / L2高速缓存中,因为该阵列的各个部分是从不同的线程填充的)。我不想求助于Kahan求和,因为我认为真正重要的是运算数量,而Kahan求和将使它增加约4倍。