seb*_*ckm 7 c++ optimization clang
考虑一下我在这个问题中发现的这个功能:
void to_bytes(uint64_t const& x, uint8_t* dest) {
dest[7] = uint8_t(x >> 8*7);
dest[6] = uint8_t(x >> 8*6);
dest[5] = uint8_t(x >> 8*5);
dest[4] = uint8_t(x >> 8*4);
dest[3] = uint8_t(x >> 8*3);
dest[2] = uint8_t(x >> 8*2);
dest[1] = uint8_t(x >> 8*1);
dest[0] = uint8_t(x >> 8*0);
}
Run Code Online (Sandbox Code Playgroud)
由于x并且dest可能指向同一内存,因此不允许编译器将其优化为单个qword移动(每行可能会更改的值x)。
到目前为止,一切都很好。
但是,如果您x按值传递,则此参数不再成立。实际上,GCC可以mov按照预期将其优化为一条简单的指令:https : //godbolt.org/z/iYj1or
但是,c不会:https : //godbolt.org/z/Hgg5z9
我假设,由于甚至不能保证完全x占用任何堆栈内存,因此在调用该函数之前进行任何dest指向操作的尝试都将导致未定义的行为,因此编译器可以假定这种情况永远不会发生。那意味着c在这里失去了一些机会。但是我不确定。有人可以澄清吗?x
您给出的代码过于复杂。您可以将其替换为:
void to_bytes(uint64_t x, uint8_t* dest) {
x = htole64(x);
std::memcpy(dest, &x, sizeof(x));
}
Run Code Online (Sandbox Code Playgroud)
是的,这使用了 Linux-ism htole64(),但是如果您在另一个平台上,您可以轻松地重新实现它。
Clang 和 GCC 在小端和大端平台上都完美地优化了这一点。