创建alignas(64)ints的向量

时间:2019-02-07 19:39:14

标签: c++ multithreading

我正在学习C ++中的并行编程。我听说,如果访问共享向量,则每个元素在内存中对齐64个字节会提高性能,因为这会减少错误共享。

如何创建std::vector<int>,其中向量中的每个元素都按64个字节对齐?使用alignas(64) vector<int>不会产生预期的效果,因为向量本身是64字节对齐的,而不是其中的每个元素。到目前为止,我发现的唯一解决方法是创建具有所需对齐方式的新结构。

struct alignas(64) int64 
{
     value; 
     int64(int a): value(a) {}
}

此解决方案的问题是我不能使用该结构,因为它是正常的int。因此,我必须调整整个代码以返回value

编辑:假设您想同时总结一个向量。一种可能性是创建计数器的共享向量,其中每个线程加总到其自己的空间中(例如,通过thread_id)。当向量的每个元素占据一条完整的界线时,错误共享(我认为)应减少。之后,可以依次总结所得向量。这是一个示例:

int false_share_sum(vector<int> &bigboy, int threads) {
    vector<int> shared_counter(threads, 0); // here each int should be 64 byte

    #pragma omp parallel for num_threads(threads)
    for (auto iter = bigboy.begin(); iter < bigboy.end(); ++iter) {
        shared_counter[omp_get_thread_num()] += *iter;
    }

    int sum = 0;
    for (auto iter = shared_counter.begin(); iter != shared_counter.end(); ++iter)
    {
        sum += *iter;
    }

    return sum;
}

1 个答案:

答案 0 :(得分:1)

这正是std::hardware_destructive_interference_sizestd::hardware_constructive_interference_size所做的事情。有关更多信息,请访问:https://en.cppreference.com/w/cpp/thread/hardware_destructive_interference_size

#include <new>
struct AlignedInt {
    alignas(std::hardware_destructive_interference_size) int value;
};

...

std::vector<AlignedInt> vec;

现在,如果您实际上要执行此操作,则是另一个问题。确保衡量您的表现,并使用最适合您实际问题的方法。如果没有破坏性的错误共享,则应将其留给编译器/ CPU。