我开始使用SSE进行操作。我想用_mm_dp_ps制作两个点产品,并在aux_sse中保存第一个结果,在aux_sse中保存第二个结果。B是一个值为1的8元向量.
因为我每对只需要两个浮点数,所以我做了以下代码:
printf("A \n");
for(i = 0; i < M; i++){
for(j = 0; j < ele; j++){
A[i*ele+j] = i*ele+j;
printf(" %f ", A[i*ele+j]);
}
printf("\n");
}
float aux[ele*M];
float aux2[ele*M];
__m128 *A_sse = (__m128*) A;
__m128 *B_sse = (__m128*) B;
__m128 *aux_sse = (__m128*) aux;
__m128 *aux2_sse = (__m128*) aux2;
for(int i = 0; i < M; i++)
{
*aux_sse = _mm_dp_ps (*A_sse, *B_sse, 0xFF);
printf("%f \n", aux[i]);
B_sse ++;
A_sse++;
*aux2_sse = _mm_dp_ps (*A_sse, *B_sse, 0xFF);
printf("%f \n", aux2[i]);
B_sse --;
A_sse ++;
aux_sse+= sizeof(char);
aux2_sse+= sizeof(char);
}我得到了以下错误的输出:
A
0.000000 1.000000 2.000000 3.000000 4.000000 5.000000 6.000000 7.000000
8.000000 9.000000 10.000000 11.000000 12.000000 13.000000 14.000000 15.000000
6.000000
22.000000
6.000000
22.000000 根据这
使用imm8中的高4位,在a和b中有条件地将封装的单精度(32位)浮点元素相乘,将四个积之和相加,并使用imm8的低4位有条件地将和存储在dst中。
我理解在imm8中,我们在元素中指定要保存结果。
据我所知,即使结果在输出向量的4个元素中,如果我只使用aux_sse+= sizeof(char)增加一个元素,则结果应该被覆盖,并得到所需的结果。不过,我看到情况并非如此。
如果在打印aux和aux2的结果时进行以下修改,则输出是正确的。
printf("%f \n", aux[i*4]);
printf("%f \n", aux2[i*4]);输出:
6.000000
22.000000
38.000000
54.000000 我正在使用gcc编译器。有人知道问题出在哪里吗?任何答案都会有帮助。
编辑:
我需要aux和aux2的元素对应于每个迭代:
auxi =在迭代1中执行的dot_product
发布于 2020-11-08 10:29:09
aux_sse+= sizeof(char);是一种无意义的编写aux_sse+=1的方法,即前进16字节,也就是4个浮点数,即sizeof(__m128) == sizeof(*aux_sse) == 16。
所以,如果你也是通过浮点索引访问数组,是的,如果你只对4个浮点数的每一个向量增加一个i,你就必须将它缩放4。
通常,使用_mm_store_ps(&aux[i], v);比跟踪__m128*变量来访问相同的数组更容易。然后执行i+=4,因此i实际上是对您拥有的4元素组的开始进行索引,而不是需要对其进行缩放。这使得编写像i < M-3这样的循环边界变得更容易。
还请注意,如果要对数组进行对齐所需的访问,则应该使用alignas(16) float aux[ele*M];。GCC注意到你在做什么,当数组可以看到它们是如何使用的时候,它会帮你对齐,但是一般不要指望它。
float 还是您只想存储一个结果,而不是为每组4个输入存储4个相同的点产品?在这种情况下,您应该提取低标量元素,例如_mm_store_ss (&aux[i], v)。或者_mm_cvtss_f32(v),将向量的低元素作为标量float。
如果您想要这样做,您可以手工完成四个4元素点产品,产生一个向量的4个结果。_mm_mul_ps,然后可能是2x _mm_hadd_ps (SSE3),水平减少,一种转置和加。(由@mainactual建议)
dpps是Skylake和类似的英特尔CPU (https://uops.info)上的4 uop,所以如果你有多个点产品要做的话,那就不太好了。
为了避免SSE3,您可以使用_mm_shuffle_ps (舒夫斯)从两个向量中选择元素,或者一些_mm_unpacklo_ps / unpackhi可能会有用,或者可以使用pd版本来将元素对放在一起。
https://stackoverflow.com/questions/64736927
复制相似问题