繁体   English   中英

高速缓存行缓存,用于缓存行大小倍数的变量

[英]Cache line padding for variables that are a multiple of cache line size

我正在创建一个非常快速的多线程离散事件仿真框架。 框架的核心使用原子和无锁编程技术来实现跨多个线程的非常快速的执行。 这需要我将一些变量与高速缓存行对齐并填充剩余的高速缓存行空间,以便我没有高速缓存行争用。 我是这样做的:

// compute cache line padding size
constexpr u64 CLPAD(u64 _objSize) {
  return ((_objSize / CACHELINE_SIZE) * CACHELINE_SIZE) +
      (((_objSize % CACHELINE_SIZE) > 0) * CACHELINE_SIZE) -
      _objSize;
}

alignas(CACHELINE_SIZE) MyObject myObj;
char padding[CLPAD(sizeof(myObj))];

这对我很有用,但是当我将这种方法用于新的对象类型时,我偶然发现了一个问题。 CLPAD()函数返回填充输入类型到下一个缓存行所需的字符数量。 但是,如果我输入一个大小恰好是缓存行数的倍数的类型,则CLPAD返回0.如果您尝试创建零大小的数组,则会收到此警告/错误:

ISO C++ forbids zero-size array 'padding'

我知道在这种情况下我可以修改CLPAD()以返回CACHELINE_SIZE,但后来我无缘无故地刻录了一个空间缓存行。

如果CLPAD返回0,如何使'padding'的声明消失?

std::aligned_storage<>页面,我想出了以下内容:

template<class T, bool = false>
struct padded
{
    using type = struct
    {
        alignas(CACHELINE_SIZE)T myObj;
        char padding[CLPAD(sizeof(T))];
    };
};

template<class T>
struct padded<T, true>
{
    using type = struct
    {
        alignas(CACHELINE_SIZE)T myObj;
    };
};

template<class T>
using padded_t = typename padded<T, (sizeof(T) % CACHELINE_SIZE == 0)>::type;

用法:

struct alignas(32) my_type_1 { char c[32]; }; // char c[32] to silence MSVC warning
struct my_type_2 { char c[CACHELINE_SIZE * 2]; }; // ditto

int main()
{
    padded_t<my_type_1> pt0;
    padded_t<my_type_2> pt1;

    sizeof(pt0);    // 128
    alignof(pt0);   // 128

    sizeof(pt1);    // 256
    alignof(pt1);   // 128
}

您可以根据需要提供访问myObj的功能。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM