gpt4 book ai didi

c++ - 这种方法是否对分支预测产生积极影响?

转载 作者:行者123 更新时间:2023-11-30 02:21:09 24 4
gpt4 key购买 nike

我一直在尝试制作一种回调函数,在这个过程中我意识到我更喜欢的回调函数也可能会改变 CPU 在后台处理分支预测的方式。我知道过度优化是应该避免的事情,尤其是在早期,但这是一种非常适合我使用的方法,并且具有避免缓存未命中的效果将是一个很好的奖励。

不过,我对 CPU 架构的了解还不足以自己回答这个问题,所以我很好奇是否有人知道这是否会影响分支预测的处理方式,以及它是否以有益的方式这样做。

我最初的解决方案是这样的:(请注意更大的 block )

enum _myenum { t1, t2, t3 }myenum; //enumerator and switch 

switch (myenum){
case t1:
{ /*a block*/ }
break;
case t2:
{ /*another block*/ }
break;
case t3:
{ /*yet another block*/ }
break;
default: break;
}

以及适合我使用的解决方案:

enum _myenum { t1, t2, t3 }myenum; //same enum
//a map of lambdas/functions
std::map<_myenum, std::function<void()>>lambda_map{
{ t1, [&]() {/*a block*/} },
{ t2, [&]() {/*another block*/ }},
{ t3, [&]() {/*yet another block*/ }}
};

lambda_map[myenum](); //to run the callback

我将在哪里运行 lambda_map[myenum](); 而不是更难跟踪的开关函数。

但是 lambda 指针映射是否可以使 CPU 免于潜在的缓存未命中?据我所知,不必预测 if 语句或运行 switch case,而是根据设置的 myenum 变量跳转到特定函数,应该可以做到这一点,对吧?或者至少以某种方式影响它。

我很好奇 lambda_map[enum](); 在分支预测和避免缓存未命中方面是否比遍历可能情况列表的 switch 语句更好。

最佳答案

Where I will run the lambda_mapmyenum; instead of the harder-to-track switch function.

这可能是误导你的原因。 switch 语句不一定比某些类似 map 的结构“更难跟踪”。事实上,由于编译器优化,它很可能实现为跳转表,即跳转指令数组,类似于您对第二个解决方案的想象。

在你的例子中,使用 std::map 几乎肯定会变慢,因为间接寻址(以及随之而来的缓存未命中),并且因为它使用二进制搜索来查找值(value)。您想要的是一个函数指针数组 (std::array)(使用 std::function 或 lambda),使用枚举数作为索引。在数组不可行的情况下(由于键的性质),可以改用散列图 (std::unordered_map)。

就性能而言,如果不进行分析,就无法判断函数数组方法是否优于编译器优化开关。

话虽如此,由于从样式( block 嵌套、放置...)到实际可维护性的个人偏好,我经常发现自己编写数组或 HashMap (函数或非函数)来代替 switch 语句。也因为我不喜欢 switch 语句的结构。对最后一部分持保留态度:我敢肯定有些人更喜欢类似开关的结构并鄙视替代方案。

关于c++ - 这种方法是否对分支预测产生积极影响?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48863565/

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