是否有任何预处理器指令可以控制循环展开?

时间:2012-10-11 00:27:14

标签: c++ visual-c++ pragma preprocessor-directive

此外,假设循环中的所有操作完全独立于其他迭代,编译器如何确定展开循环的程度。

2 个答案:

答案 0 :(得分:6)

对于MSVC,只有一个向量独立提示:http://msdn.microsoft.com/en-us/library/hh923901.aspx

#pragma loop( ivdep )

对于许多其他编译器,例如Intel / ibm,有几个用于优化循环的编译指示提示:

#pragma unroll
#pragma loop count N
#pragma ivdep

有一个关于展开启发式的MSVC ++人员的帖子:http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/d0b225c2-f5b0-4bb9-ac6a-4d4f61f7cb17/

  

VC尝试平衡执行速度和代码大小。您可以使用flags / O1或/ O2更改余额,但即使优化速度VC也会尝试节省代码大小。

基本上,展开会增加代码大小,因此在Os和O1模式下可能会受到限制(modes table

PS:Pragma看起来像预处理器指令,但事实并非如此。它是编译器的指令,它被预处理器忽略(保留)。

答案 1 :(得分:2)

对于英特尔编译器:

#pragma loop count N 帮助编译器使用最佳策略来对循环进行矢量化。它节省了时间因此,我们可以说它有助于推动循环展开。 例子:

#pragma loop_count min(n),max(n),avg(n)

#pragma unroll(n)仅在与-O3标志一起使用时才有效,您可以使用以下策略根据目标处理器展开循环。

除了循环展开生成的增加的代码之外,它可能是值得的,因为编译器将为标量操作以及向量操作生成循环版本。

在展开影响性能的情况下,例如:循环使用向量长度为​​16的20次迭代,导致1个循环一次执行16个操作,而余数循环按顺序执行4个。 为了避免编译器生成的余数循环,我们可以在循环之前使用:

#pragma vector novecremainder //or -mP2OPT_hpo_vec_peel = F to disable peel and remainder loops (compiler internal option)

#pragma nounroll //where unrolling is not worth at all 

只是为了澄清 #pragma ivdep

  • 它提供了修改关于依赖项的编译器启发式的特定提示,并且只有在我们知道假定的依赖项可以安全忽略时才能使用它。
  • 最重要的是,它会覆盖潜在的依赖关系,但编译器仍会执行依赖性分析,无论进行任何分析,都可以尝试使用#pragma simd进行向量化。

希望这会有所帮助。