创建 alignas(64) 整数的向量

Posted

技术标签:

【中文标题】创建 alignas(64) 整数的向量【英文标题】:Create vector of alignas(64) ints 【发布时间】:2019-02-07 19:39:13 【问题描述】:

我正在学习 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;

【问题讨论】:

你实际上用这个做什么?可能有更好的方法来做到这一点,然后将整个缓存行用于单个 int 这很奇怪。通常,将向量对齐 64 字节是我们想要的,而不是对齐单个整数。 单个int 会有更好的对齐,但是你会增加总内存占用,这会对缓存的友好性产生负面影响,可能刚好足以抵消对齐元素的增益,也许更多 关于“我听说如果...对性能有好处”,答案是:profile,profile,profile。如果您出于性能原因进行更改,并且您没有衡量性能增益(或损失......!),那么您只是在拉线是随机的,并且可能有害而不是有益。尤其是当代码更难阅读、更难维护时,危害会更加严重。 我认为,你被误导了。将整个缓存用于单个 int 几乎会使缓存无用。避免错误共享的更好方法是更明智地在线程之间分配负载。 【参考方案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。

【讨论】:

以上是关于创建 alignas(64) 整数的向量的主要内容,如果未能解决你的问题,请参考以下文章

boost aligned_allocator 对齐参数不影响实际对齐

关于结构体内存对齐方式的总结(#pragma pack()和alignas())

使用 192/256 位整数对无符号 64 位整数向量的点积求和的最快方法?

在 LLVM IR 中,将整数存储到向量的第二个元素中

内存对齐:如何使用 alignof / alignas?

如何创建一个给定正整数的函数,返回一个向量,该向量的数字是 5 的倍数?