Skip to content

struct/class that require cacheline alignment may not work when using new (before c++17). #2416

@ehds

Description

@ehds

Is your feature request related to a problem? (你需要的功能是否与某个问题有关?)
当前 brpc 代码默认使用的 C++ 标准为 11,不支持 align new (since c++17 https://en.cppreference.com/w/cpp/memory/new/operator_new) .

如果某个 class 指定了 alignment 要求(例如 BAIDU_CACHELINE_ALIGNMENT),代码中使用 new 的方式来分配其对象时,地址有可能并不是严格按照其对齐方式的。

要让一个变量或结构体按cacheline对齐,可以include <butil/macros.h>后使用BAIDU_CACHELINE_ALIGNMENT宏,请自行grep brpc的代码了解用法。

https://github.com/apache/brpc/blob/master/docs/cn/atomic_instructions.md#cacheline

例如以下代码,使用当前的编译选项,就可能会出现错误。

class BAIDU_CACHELINE_ALIGNMENT A {
    int i;
};

int main() {
    for(size_t i =0 ;i<100;i++) {
        A* a = new A();
        // maybe fail.
        assert((reinterpret_cast<uintptr_t>(a) & (63)) == 0);
     }

Describe the solution you'd like (描述你期望的解决方法)

使用 new 来分配指定对齐要求的类时,内存地址应满足对齐的要求。
升级为 C++17 标准,或者开启 -faligned_new (gcc 7.4+,clang 7.1.0+ 都已经支持) .

目前来看是强行关闭了该警告信息(不知道具体原因).

brpc/CMakeLists.txt

Lines 70 to 72 in f3fe5fc

if(NOT (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.0))
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-aligned-new")
endif()

Describe alternatives you've considered (描述你想到的折衷方案)
对于需要对齐的类,在使用 new 分配内存时使用 aligned_alloc/posix_memalign 等函数申请 alignment 内存,再使用 Placement new 指定内存空间进行初始化.

Additional context/screenshots (更多上下文/截图)
os: 20.04.1-Ubuntu
compiler: clang version 10.0.0-4ubuntu1
cpu: x86_64, cache_alignment : 64 byte

例如对于 class BAIDU_CACHELINE_ALIGNMENT/*note*/ Socket 类:

image

socket 的地址为 0x00005555567f1530, 并不是 64 byte 对齐,违反了要求,可能引起 false-sharing.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions