在 C++ Core Guidelines Per.4 中,为什么坏示例旨在更快?
In C++ Core Guidelines Per.4, why is the bad example intended to be faster?
我最近正在阅读 this,其中指出:
Don’t assume that complicated code is necessarily faster than simple code.
代码复制如下:
例子,很好
// clear expression of intent, fast execution
vector<uint8_t> v(100000);
for (auto& c : v)
c = ~c;
示例,不好
// intended to be faster, but is often slower
vector<uint8_t> v(100000);
for (size_t i = 0; i < v.size(); i += sizeof(uint64_t)) {
uint64_t& quad_word = *reinterpret_cast<uint64_t*>(&v[i]);
quad_word = ~quad_word;
}
我不确定坏例子的目的是什么,为什么想要更快?
为什么它 实际上通常更慢?
通过将指针转换为 64 位整数并对该整数执行按位运算,您可以将 C++ 代码执行的运算次数减少 8 倍。也就是说,所做的假设是性能取决于用 C++ 代码编写的操作数。
编译器会尝试通过使用 SIMD 指令一次执行多个操作来向量化操作(SSE/AVX 在 x86-64 上,其他在其他平台上)。
通过使用 uint64_t
手动向量化,您可以让编译器一次执行 8 个操作,您认为这是对调试构建的改进,但可能会阻止它一次进行更多操作(例如,16 个SSE2,AVX2 为 32,AVX512 为 64),您认为它的发布速度较慢。
我最近正在阅读 this,其中指出:
Don’t assume that complicated code is necessarily faster than simple code.
代码复制如下:
例子,很好
// clear expression of intent, fast execution
vector<uint8_t> v(100000);
for (auto& c : v)
c = ~c;
示例,不好
// intended to be faster, but is often slower
vector<uint8_t> v(100000);
for (size_t i = 0; i < v.size(); i += sizeof(uint64_t)) {
uint64_t& quad_word = *reinterpret_cast<uint64_t*>(&v[i]);
quad_word = ~quad_word;
}
我不确定坏例子的目的是什么,为什么想要更快?
为什么它 实际上通常更慢?
通过将指针转换为 64 位整数并对该整数执行按位运算,您可以将 C++ 代码执行的运算次数减少 8 倍。也就是说,所做的假设是性能取决于用 C++ 代码编写的操作数。
编译器会尝试通过使用 SIMD 指令一次执行多个操作来向量化操作(SSE/AVX 在 x86-64 上,其他在其他平台上)。
通过使用 uint64_t
手动向量化,您可以让编译器一次执行 8 个操作,您认为这是对调试构建的改进,但可能会阻止它一次进行更多操作(例如,16 个SSE2,AVX2 为 32,AVX512 为 64),您认为它的发布速度较慢。