【问题标题】:Is the preference with SIMD to always get rid of branching?SIMD 的偏好是否总是摆脱分支?
【发布时间】:2012-02-12 17:54:14
【问题描述】:

如果您正在编写一些将由另一个程序运行的 SIMD 代码,那么摆脱分支以提高性能总是有利的吗?我听说即使只是为了避免if/else 语句等而进行额外的操作仍然要快得多。

我问这个是因为我做了一些分支,基本上是这样的:

//  axis; x=0, y=1, z=2

float p, q;
if (axis == 0)
{
    p = point.y;
    q = point.z;
}
else if (axis == 1)
{
    p = point.x;
    q = point.z;
}
else if (axis == 2)
{
    p = point.x;
    q = point.y;
}

我可以通过一些巧妙的技巧来避免这种分支吗?

【问题讨论】:

  • 这真的取决于分支是否可预测。如果您连续多次使用相同的“axis”值调用此函数,那么这种方式会更好。如果axis 看起来很随机,那么值得优化它们。如果您可以在设置axis 的代码中内联它,那么这无关紧要,因为无论如何您都不会得到分支。
  • 谢谢,所有调用的轴都是固定的。另外,内联是指仅内联适当的分支吗?如果是这样,那将是甜蜜的。我会检查编译器是否这样做。
  • 如果这个函数内联,那么生成的代码应该只有采用的分支。如果这个函数太大而不能内联,您可能希望为每个轴值(只有那个分支)制作一个函数版本,然后有一个“包装器”函数进行内联,它选择适当的非内联函数axis 的值。内联包装器应该消除分支并调用正确的无分支函数。
  • 另外这其实是在主函数中,而不是在单独的函数中。如果我将它分成另一个函数或将它保留在主函数中,这有关系吗?我认为它不是太大或通用,并且与主要功能非常相关,因为没有其他人使用它。

标签: c++ performance optimization concurrency simd


【解决方案1】:

大多数 SIMD 架构都有特殊指令,可让您根据掩码向量有条件地选择元素。掩码向量通常是 SIMD 比较指令的结果。所以是的,很容易摆脱上面示例中的那种分支。

您是否真的需要摆脱任何给定的分支,但这取决于各种因素,例如分支的可预测性、数据的性质(统计数据)以及执行的代码量有条件的。根据经验,无分支是好的,但与大多数规则一样,也有例外。

【讨论】:

  • 谢谢,实际上程序在知道值是固定的情况下调用我的函数,但如果我愿意,我可以在程序中使其成为动态的,但即便如此程序也会意识到该值与这是调用我的函数的那个​​。我不确定它是否使用此信息。是否会在分支中打印某些内容并查看它是否打印一次或为每个实体/元素打印证明编译器实际上对此进行了优化?
  • 如果不知道您使用的是什么 CPU、编译器等,很难给出具体的建议。通常你想查看生成的代码(例如gcc -S)和/或使用分析器来识别性能瓶颈。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-28
  • 1970-01-01
  • 2020-10-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多