【发布时间】:2018-07-29 12:49:49
【问题描述】:
我一直在尝试创建一种回调函数,在此过程中我意识到我更喜欢的回调函数也可能会改变 CPU 在后台处理分支预测的方式。我知道过度优化是一个应该避免的事情,尤其是在早期,但这是一种非常适合我使用的方法,并且具有避免缓存未命中的效果将是一个很好的奖励。
但是,我对 CPU 架构的了解不足以自己回答这个问题,所以我很好奇是否有人知道这是否会影响分支预测的处理方式,以及它是否以有益的方式这样做。
我的初始解决方案如下所示:(请注意较大的块)
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 案例,而是根据 set myenum 变量跳转到特定函数,应该可以做到这一点,对吧?或者至少以某种方式影响它。
我很好奇 lambda_map[enum](); 在分支预测和避免缓存未命中方面是否比通过可能情况列表的 switch 语句更好。
【问题讨论】:
-
根据枚举值,
std::array会比map更好。 -
您是否只是因为不喜欢
switch声明而想要更改?或者你有没有测量和分析发现它是你代码中的一个实际瓶颈?还是您刚刚落入过早优化的陷阱?首先编写好的、可读和可维护的代码。然后,如果它不是“足够好”(通常是足够好),则测量和分析以找到瓶颈并仅修复这些瓶颈(使用大量 cmets 和文档)。 -
@Someprogrammerdude 我在问题中提到它不是为了优化,而是出于好奇
-
您正在用地图(或数组,如 Jarod42 建议的那样)查找来替换可能的分支预测错误:我在这个领域不是很专家,但我假设您正在减慢您的程序而不是提高性能
-
您应该使用
map.find只进行一次查找。
标签: c++ branch-prediction