这种方法是否对分支的预测产生了影响
Does this approach positvely impact branch prediction?
我一直在尝试制作一种回调函数,在此过程中,我意识到我喜欢的回调功能也可能会改变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-Pointer地图是否会从潜在的缓存中保存CPU?就像我所收集的那样,不必预测语句或通过开关案例运行,而是基于集合myenum
变量跳到特定功能,应该做到这一点,对吗?或至少以某种方式影响它。
我很好奇lambda_map[enum]();
是否可以在分支机构预测和避免缓存失误上更好,而不是通过可能的情况列表的开关语句。
我将在哪里运行lambda_mapmyenum;而不是更困难的轨道开关功能。
这可能是误导您的原因。开关语句不一定比某些类似地图的结构"更难跟踪"。实际上,由于编译器的优化,它很可能会作为跳台实现,这是一系列跳跃指令,类似于您想象的第二个解决方案。
在您的情况下,使用std::map
几乎可以保证会因为间接而变慢(并且与之相处的高速缓存(,并且因为它使用二进制搜索来找到一个值。您想要的是功能指针的数组(std::array
((使用std::function
或Lambdas(,使用枚举器作为索引。如果数组不可行(由于密钥的性质(,则可以使用hashmap(std::unordered_map
(。
在性能方面,无法分析,无法分析,功能障碍方法是否击败了编译器优化的开关。
话虽如此,我经常发现自己编写了阵列或哈希图(功能与否(,而不是Switch语句,因为个人偏好范围从样式(块嵌套,位置,...(到实际可维护性。也是因为我不喜欢开关语句的结构。将最后一部分撒上一粒盐:我敢肯定有些人喜欢类似开关的结构并鄙视替代方案。
- Clang 给了我符号更改的警告,但代码仍然产生正确的输出
- 这会对代码产生任何影响吗?
- 在渲染之前直接上传是否会对性能产生负面影响
- 我做了自己的std ::矢量,但我正在产生错误
- imshow() 在 C++ 年使用 OpenCV 3.2 产生了奇怪的结果
- 这种方法是否对分支的预测产生了影响
- 我通过编译器C 11收到了UVA在线法官的错误消息.我永远不知道为什么会产生此错误
- 传递const引用参数的意义是什么?它会产生重大影响吗
- 链接到CMake目标会产生什么影响
- 为什么这个C++程序的输出在cmd中产生了巨大的混乱
- 代码的后一部分在某种程度上影响了前一部分
- C++程序产生了许多错误
- 注释在运行时是否可以产生任何影响
- gluLookAt似乎产生了错误的观点,OpenGL
- zlib compress() 产生了可怕的压缩率
- 为什么包括警卫对我没有影响?我是不是错过了什么
- 我的弹射器游戏产生了不正确的距离
- 我的c++程序读取一个矩阵并打印出非零的数字,这产生了一个运行时错误
- dlopen是否重新加载已加载的依赖项?如果是,会产生什么影响
- Lorenz示例中的odeint和VecCL在不同的设备上产生了不同的结果