锐英源软件
第一信赖

精通

英语

开源

擅长

开发

培训

胸怀四海 

第一信赖

当前位置:锐英源 / 开源技术 / C++开源社区 / C++17 过度对齐分配 /Zc:alignedNew

服务方向

人工智能数据处理
人工智能培训
kaldi数据准备
小语种语音识别
语音识别标注
语音识别系统
语音识别转文字
kaldi开发技术服务
软件开发
运动控制卡上位机
机械加工软件
量化预测
股票离线分析软件
软件开发培训
Java 安卓移动开发
VC++
C#软件
汇编和破解
驱动开发

联系方式

固话:0371-63888850
手机:138-0381-0136
Q Q:396806883
微信:ryysoft

锐英源精品原创,禁止转载和任何形式的非法内容使用,违者必究。点名“简易百科”和“闲暇巴”盗用锐英源原创内容。


C++17 过度对齐分配 /Zc:alignedNew


C++17 过度对齐分配的英文是over-aligned allocation,其实这个翻译是有问题的,over是过的大的意思,翻译成大对齐分配或大值对齐分配就可以了,过度这个词明显是机器翻译的结果,不是意思翻译的结果。过度对齐分配理解成大值对齐分配,大家就明白了,相当于对齐值变大了。

对齐值变大有什么好处?现代CPU的数据总线结构和地址总线结构复杂且强大,寻址功能和提取写入数据功能也比以前优秀,硬件改动了,也要让软件改动,对齐值变大了,让寻址功能和提取写入数据功能更容易体现到软件运行上,特别是内存池和共享文件内存处理上,对齐的内存读写更快,效率更高。

在电脑和互联网刚传入到国内时,很多自己开发的软件在性能上总是差那么一丝丝,这就是底层硬件的处理没吃透,不过随着华为带领一批公司崛起,硬件吃透了,软件性能也跟上了。这中间华为方舟编译器是里程碑事件,华为方舟编译器把Java解释代码编译成静态代码,提升了性能。华为方舟编译器支持多种芯片平台,和上段话的CPU结构对应上了。

说了这么多,就是说内存对齐能优化软件性能,C++17以前对齐值太小,不支持硬件了。

开启过度对齐分配,在编译选项里加上/Zc:alignedNew,加上后,如果对齐值小于宏__STDCPP_DEFAULT_NEW_ALIGNMENT__,则没有改变;如果大于宏__STDCPP_DEFAULT_NEW_ALIGNMENT__则使用新的::operator new(size_t, align_val_t) 获取内存,新的::operator delete(void*, align_val_t) 或特定大小的删除函数 ::operator delete(void*, size_t, align_val_t)。

要关闭此选项并在使用 /std::c++17 或更高版本时恢复到 new 和 delete 的 C++14 行为,请指定 /Zc:alignedNew-。

参考的新new和新delete示例如下:

// alignedNew.cpp
// Compile by using: cl /EHsc /std:c++17 /W4 alignedNew.cpp
#include <iostream>
#include <malloc.h>
#include <new>

// "old" unaligned overloads
void* operator new(std::size_t size) {
    auto ptr = malloc(size);
    std::cout << "unaligned new(" << size << ") = " << ptr << '\n';
    return ptr ? ptr : throw std::bad_alloc{};
}

void operator delete(void* ptr, std::size_t size) {
    std::cout << "unaligned sized delete(" << ptr << ", " << size << ")\n";
    free(ptr);
}

void operator delete(void* ptr) {
    std::cout << "unaligned unsized delete(" << ptr << ")\n";
    free(ptr);
}

// "new" over-aligned overloads
void* operator new(std::size_t size, std::align_val_t align) {
    auto ptr = _aligned_malloc(size, static_cast<std::size_t>(align));
    std::cout << "aligned new(" << size << ", " <<
        static_cast<std::size_t>(align) << ") = " << ptr << '\n';
    return ptr ? ptr : throw std::bad_alloc{};
}

void operator delete(void* ptr, std::size_t size, std::align_val_t align) {
    std::cout << "aligned sized delete(" << ptr << ", " << size <<
        ", " << static_cast<std::size_t>(align) << ")\n";
    _aligned_free(ptr);
}

void operator delete(void* ptr, std::align_val_t align) {
    std::cout << "aligned unsized delete(" << ptr <<
        ", " << static_cast<std::size_t>(align) << ")\n";
    _aligned_free(ptr);
}

struct alignas(256) OverAligned {}; // warning C4324, structure is padded

int main() {
    delete new int;
    delete new OverAligned;
}

注意,里面的delete new连接使用非常新,以前没想到过能这样用。

如果自己没有写新new和delete,编译器在有编译宏/Zc:alignedNew时会自动生成新new和delete。

硬件我也是略懂,我猜测,过度对齐大值对齐内存可能更好支持CPU的某些并发访问存取,在大游戏和高算力场景有需求。

友情链接
版权所有 Copyright(c)2004-2024 锐英源软件
统一社会信用代码:91410105098562502G 豫ICP备08007559号 最佳分辨率 1440*900
地址:郑州市金水区文化路97号郑州大学北区院内南门附近