0

感谢你们中的一些人,我已经使用 SSE 来加速计算我在C++ 中的科学应用程序的一项功能,使用 SSE 指令来比较巨大的 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,我需要为自定义向量分配器编写整个代码吗?有没有更简单的选择?

我需要你的帮助。提前致谢

4

1 回答 1

1

您可以做几件事来稍微提高性能:

  • 退出循环,但这很__m128i v1, v2, vmax;可能是由编译器完成的
  • 确保距离正确对齐
  • 而不是使用 std::vector,对齐数据并传递指针。然后使用_mm_load_si128.

如果距离和goalNodeIdTemp 正确对齐,您可以使用原始指针。像这样的东西:

__m128i *v1 = (__m128i *) & distances[positionNodeId + k];
__m128i *v2 = (__m128i *) & goalNodeIdTemp[k];

所有进一步的优化,您需要查看汇编代码。


如果两者都对齐,您是否相信我可以获得更好的速度:a)数组距离对齐 b)向量 goalNodeIdTemp 对齐

是的,您将获得小的性能提升。没什么了不起的,但如果每个周期都很重要,那么它可能会很明显

我怎么做?

goalNodeIdTemp对齐,您必须使用特殊的分配器std::vector(例如,请参见此处的操作方法)。

要对齐distance,你必须小心一点。请参阅此处如何分配对齐的内存。

于 2013-07-25T11:45:00.287 回答