gpt4 book ai didi

c++ - 优化删除内存

转载 作者:行者123 更新时间:2023-12-01 14:50:23 25 4
gpt4 key购买 nike

为了避免破坏严格的别名规则,我在代码中的几个地方引入了memcpy,希望它是no-op。以下示例在gcc和clang上生成对memcpy(或等效代码)的调用。具体来说,fool<40>总是会执行,而foo会在gcc上执行,而不会在clang上执行,而fool<2>会在ccc上执行但在gcc上不会执行。何时/如何对其进行优化?

uint64_t bar(const uint16_t *buf) {
uint64_t num[2];
memcpy(&num, buf, 16);
return num[0] + num[1];
}

uint64_t foo(const uint16_t *buf) {
uint64_t num[3];
memcpy(&num, buf, sizeof(num));
return num[0] + num[1];
}

template <int SZ>
uint64_t fool(const uint16_t *buf) {
uint64_t num[SZ];
memcpy(&num, buf, sizeof(num));
uint64_t ret = 0;
for (int i = 0; i < SZ; ++i)
ret += num[i];
return ret;
}

template uint64_t fool<2>(const uint16_t*);
template uint64_t fool<40>(const uint16_t*);

还有一个 link to the compiled output (godbolt).

最佳答案

我真的不能告诉您为什么各个编译器无法按照您希望它们在特定情况下进行优化的方式来优化代码。我猜每个编译器要么无法跟踪目标阵列与源内存之间的memcpy建立的关系(如我们所见,它们似乎至少在某些情况下确实认识到这种关系),或者只是具有某种启发式的判断力他们选择不使用它。

无论如何,由于编译器似乎不像我们希望的那样依赖于它们跟踪整个数组,因此我们可以尝试通过仅在每个元素的基础上执行memcpy使其对编译器更加明显。这seems to produce the desired result on both compilers。请注意,我必须手动展开barfoo中的初始化,否则clang会再次进行复制。

除此之外,请注意,在C++中,应该使用std::memcpystd::uint64_t等,因为标准 header are not guaranteed还将这些名称引入了全局 namespace (尽管我不知道有没有实现此目的的实现)。

关于c++ - 优化删除内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53490868/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com