感谢你们中的一些人,我已经使用SSE来加速计算C++ use SSE instructions for comparing huge vectors of ints中我的科学应用程序的一个功能。
优化的SSE功能的最终版本是:
int getBestDiffsSse(int nodeId, const vector<int> &goalNodeIdTemp) {
int positionNodeId = 2 * nodeId * nof;
int myNewIndex = 2 * nof;
int result[4] __attribute__((aligned(16))) = {0};
__m128i vresult = _mm_set1_epi32(0);
__m128i v1, v2, vmax;
for (int k = 0; k < myNewIndex; k += 4) {
v1 = _mm_loadu_si128((__m128i *) & distances[positionNodeId + k]);
v2 = _mm_loadu_si128((__m128i *) & goalNodeIdTemp[k]);
v1 = _mm_xor_si128(v1, vke);
v2 = _mm_xor_si128(v2, vko);
v1 = _mm_sub_epi32(v1, vke);
v2 = _mm_sub_epi32(v2, vko);
vmax = _mm_add_epi32(v1, v2);
vresult = _mm_max_epi32(vresult, vmax);
}
_mm_store_si128((__m128i *) result, vresult);
return max(max(max(result[0], result[1]), result[2]), result[3]);
}
其中
const __m128i vke = _mm_set_epi32(0, -1, 0, -1);
const __m128i vko = _mm_set_epi32(-1, 0, -1, 0);
和
int* distances
distances= new int[size];
大小很大(18M x 64)
我天真的问题是:如果两者都相符,你相信我可以获得更好的加速:a)阵列距离对齐或b)矢量goalNodeIdTemp对齐并且 c)我该怎么做?
我看过一些关于memalign或align_malloc的帖子,但我不明白如何将它们用于动态数组或向量。或者既然我说的是整数,那么对齐不是问题吗?请记住我使用的是Ubuntu 12.04和gcc,因此不能选择Visual Studio编译器的解决方案。
添加了问题:首先,以下代码足以对齐动态数组(请记住,定义和初始化必须保持不同);
int *distances __attribute__((aligned(16)));
distances = new int[size];
第二,为了对齐矢量goalNodeIdTemp,我是否需要为自定义矢量分配器编写整个代码?有更简单的替代方案吗?
我需要你的帮助。提前致谢
答案 0 :(得分:1)
您可以采取一些措施来改善表现:
__m128i v1, v2, vmax;
带出循环,但这很可能是由编译器_mm_load_si128
。如果distance和goalNodeIdTemp已正确对齐,则可以使用原始指针。像这样:
__m128i *v1 = (__m128i *) & distances[positionNodeId + k];
__m128i *v2 = (__m128i *) & goalNodeIdTemp[k];
所有进一步优化,您需要查看汇编代码。
如果两者都相信我相信我可以获得更好的加速:a)阵列距离对齐b)矢量goalNodeIdTemp已对齐
是的,你会得到一个小的性能提升。没什么了不起的,但是如果每个周期都计算在内,那么它可能会引人注目
我该怎么做?
要goalNodeIdTemp
对齐,您必须为std::vector
使用特殊的分配器(例如,参见here如何操作)。
要对齐distance
,你必须要小心一点。请参阅here如何分配对齐的内存。