洗白指针会破坏优化机会吗?

Do laundered pointers destroy optimisation opportunities?

提问人:bitmask 提问时间:10/30/2023 最后编辑:user3840170bitmask 更新时间:11/2/2023 访问量:243

问:

std::launder 故意混淆抽象机器/编译器的指针的来源,以便源和结果可能具有不同的生存期和类型。例如,当用于(静态)矢量情况时,您有一个容纳许多对象的半大型存储,将“干”指针洗涤到切片会产生一个干净但“湿”的指针(湿的,如洗涤):

// appropriately sized and aligned data member
std::byte* const dry = data + some_index;
T* const wet = std::launder(reinterpret_cast<T*>(dry));

这个想法是编译器无法“看到”过去。问题在于,这是否会使合法的优化机会付出代价。std::launder

例如:

T object;
// ...
T* ptr = &object;
ptr->member = 42;
return ptr->member;

据推测,在读取其内容时不需要单独检索 和 的地址,因为它可能仍位于某个寄存器中。但是,如果访问总是被清洗的,例如,如果它是从一些必须清洗存储指针的人那里检索的,那么这可能不再是真的:objectmemberptroperator[](size_type)

storage[i].member = 42;
return storage[i].member;
// storage[]() launders
  • 我对优化围栏的理解是否正确?
  • 这是否意味着由于洗涤,必须在装配级别重新加载(子)对象?
    • 如果不是,为什么不呢?
  • 除了保留对 的引用之外,还有其他方法可以解决这个问题吗?storage[i]

含义:如果这是正确的,则意味着类向量结构(即在需要最大性能时使用的结构)将在 C++14 和 C++17 之间受到性能影响,因为引入了 。 会落后于一个简单的.std::launderstd::vector<T>T*

C++ 优化 语言-律师 机器代码 stdlaunder

评论

0赞 GSerg 10/30/2023
if this may cost legitimate optimisation opportunities- 人们应该这样假设
1赞 aschepler 10/31/2023
我不认为是这样。它不会像那样对“假设”规则产生任何影响。添加它时,将具有未定义行为的程序执行更改为完全有效的程序执行。std::laundervolatile
0赞 Louis Go 10/31/2023
@gserg您链接到一个帖子“对最有效的整数比较函数进行基准测试的错误方法”,但我没有找到关键字。你能解释一下吗?它与传播有关吗?launderconst
1赞 GSerg 10/31/2023
@LouisGo 不,这与这样一个事实有关,即当编译器可以将代码视为一个整体时,它可以比必须单独优化每个函数时更好地优化它。
0赞 bitmask 11/6/2023
@GSerg 这与单独的编译单元无关。假设编译器可以看到所有代码,就好像所有代码都是在头文件中实现的一样。

答: 暂无答案