我想要优化的代码基本上是一个简单但大型的算术公式,自动分析代码以并行计算独立的乘法/加法应该相当简单,但我读到自动向量化仅适用于循环。
我已经读过多次了,应该不惜一切代价避免通过联合或其他方式访问向量中的单个元素,而应该用 _mm_shuffle_pd 代替(我只处理双打)...
我似乎不知道如何将 __m128d 向量的内容存储为双精度,而不将其作为联合访问。另外,与标量代码相比,这样的操作是否会带来任何性能增益?
union {
__m128d v;
double d[2];
} vec;
union {
__m128d v;
double d[2];
} vec2;
vec.v = index1;
vec2.v = index2;
temp1 = _mm_mul_pd(temp1, _mm_set_pd(bvec[vec.d[1]], bvec[vec2[1]]));
另外,这两个联合看起来丑陋得可笑,但是当使用时
union dvec {
__m128d v;
double d[2];
} vec;
尝试将 indexX 声明为 dvec,编译器抱怨 dvec 未声明。
不幸的是,如果你看一下 MSDN,它是这样说的:
You 不应该访问__m128d 字段directly. 但是,您可以在调试器中看到这些类型。__m128 类型的变量映射到 XMM[0-7] 寄存器。
我不是 SIMD 专家,但这告诉我你所做的事情不会起作用,因为它不是设计的。
EDIT:
我刚刚找到了这个 http://www.rz.uni-karlsruhe.de/rz/docs/VTune/reference/Intrins_API.htm,它说:
仅在赋值的左侧使用 __m128、__m128d 和 __m128i,作为返回值或参数。请勿在其他算术表达式中使用它,例如“+”和“>>”。
它还说:
在聚合中使用 __m128、__m128d 和 __m128i 对象,例如联合(例如,用于访问浮点元素)和结构。
所以也许你可以使用它们,但只能在工会中使用。然而,这似乎与 MSDN 所说的相矛盾。
EDIT2:
这是另一个有趣的资源,通过示例描述了如何使用这些 SIMD 类型 http://locklessinc.com/articles/interval_arithmetic/
在上面的链接中,您会发现这一行:
#include <math.h>
#include <emmintrin.h>
double in1_min(__m128d x)
{
return x[0];
}
在上面我们使用 gcc 4.6 中的新扩展来通过索引访问高低部分。旧版本的 gcc 需要使用并集并写入两个双精度数的数组。这很麻烦,而且当优化关闭时速度会特别慢。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)