繁体   English   中英

分支上的缓存未命中罚款

[英]Cache miss penalty on branching

我想知道用2个乘法代替分支是否更快(由于高速缓存未命中罚款)?
这是我的情况:

float dot = rib1.x*-dir.y + rib1.y*dir.x;

if(dot<0){
    dir.x = -dir.x;
    dir.y = -dir.y;
}

我正在尝试将其替换为:

float dot = rib1.x*-dir.y + rib1.y*dir.x;

int sgn = (dot  < 0.0) - (0.0 < dot ); //returns -1 or 1 (no branching here, tested)
dir.x *= sgn;
dir.y *= sgn;

分支并不意味着高速缓存未命中:只有指令的预取/流水线受到干扰,因此有可能在编译时使用它来阻止一些SSE优化。

另一方面,如果仅使用x86指令,则推测执行将使处理器正确启动最常用的分支的执行。

另一方面,如果您输入的if在50%的情况下处于最坏的情况:在这种情况下,我将尝试查找SSE流水线并使用SSE优化执行,可能会从中得到一些提示这篇文章 ,与您的第二段代码一致。

但是,对您的代码进行基准测试,检查生产的汇编程序,以找到用于此优化的最佳解决方案,并获得正确的见解。 并最终使我们保持更新:)

乘法的成本取决于几个因素,是使用32位还是64位浮点数,以及是否启用SSE。 根据此消息来源,两个float乘法的成本为10个周期: http//www.agner.org/optimize/instruction_tables.pdf

分支机构的成本还取决于几个因素。 根据经验,不必担心代码中的分支。 分支预测器在CPU上的确切行为将定义性能,但是在这种情况下,您应该期望分支充其量是不可预测的,因此这很可能导致许多分支预测错误。 根据此消息来源,分支错误预测的成本为10到30个周期: http : //valgrind.org/docs/manual/cg-manual.html

任何人都可以在此处提供的最佳建议是进行概要分析和测试。 我猜想在现代的Core i7上, if the range of input varies sufficiently as to cause sufficient branch mispredictions as to outweigh the cost of the additional multiplicationif the range of input varies sufficiently as to cause sufficient branch mispredictions as to outweigh the cost of the additional multiplication两个乘法应该比分支更快。

假设未命中率为50%,则分支的成本平均为15个周期(30 * 0.5),浮点mul的成本为10个周期。


编辑 :添加了链接,更新了估计的教学成本。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM