【问题标题】:Can I make #Pragma unroll accept macros/expressions rather than plain numbers?我可以让#Pragma unroll 接受宏/表达式而不是普通数字吗?
【发布时间】:2023-03-25 03:20:01
【问题描述】:

我试图告诉我的编译器使用#pragma unroll 为我展开一个循环。但是,迭代次数由编译时变量决定,因此循环需要展开那么多次。像这样:

#define ITEMS 4

#pragma unroll (ITEMS + 1)
for (unsigned int ii = 0; ii <= ITEMS; ++ii) 
    /* do something */;

不过,编译器不喜欢这样,因为它给了我以下警告:warning: extra characters in the unroll pragma (expected a single positive integer), ignoring pragma for this loop。我当然理解这意味着什么:它需要一个整数而不是表达式。不过,有没有办法做到这一点,而无需在每次更改 ITEMS 时更改展开参数?

我使用的编译器是CUDA的NVCC编译器。

【问题讨论】:

  • 它是否适用于#define ITEMS 5#pragma unroll ITEMS,然后是for(..., ii &lt; ITEMS; ...)
  • 是的,这会起作用,除了 ITEMS 在我的代码中的更多地方使用这一事实,并且将其定义为太多会很奇怪。我也尝试过的是#define ITEMS_PLUS_ONE (ITEMS + 1),但这会给出相同的“额外字符”警告。
  • #define ITEMS_PLUS_ONE 5#define ITEMS (ITEMS_PLUS_ONE - 1)? (如果可行,丑陋的解决方法总比没有好。)
  • 哈哈,真有趣。是的,这确实可行,并且将是一个不那么优雅但有效的解决方法。 :-) 我现在会处理它。但我想我正在寻找一个更一般的答案,如果有另一个技巧可以让编译器读取这个 pragma 中的表达式。
  • 是的,更好的解决方案肯定会很好。但我不知道如何让预处理器计算 ITEMS + 1 以便编译指示得到它想要的单个整数,所以丑陋的解决方法是我能提供的最好的。

标签: c cuda pragma nvcc loop-unrolling


【解决方案1】:

你可以反过来做:

注意:刚刚注意到 Daniel Fischer 的评论,这表明在我之前完全一样。

#define ITEMS_PLUS_ONE 5
#define ITEMS (ITEMS_PLUS_ONE - 1)

问题是预处理器不做数学运算。它只会复制和粘贴。
当你写 #define ITEMS_PLUS_ONE (ITEMS + 1) 时,unroll 被替换为 (4 + 1),而不是 5
一旦到达编译器,就没有关系了。即使没有优化,在编译的时候也会计算,(4 + 1)5完全一样。
但是在你的编译器中,#pragma unroll是在编译前处理的,需要简单的数字。

【讨论】:

  • 有道理,谢谢。换句话说:因为预处理器不能做数学运算,所以没有办法以一种不可解决的方式做到这一点,对吧?
  • @Jelle,对。一些编译器接受带有表达式的#pragma unroll,您的编译器不接受。因为它没有,所以你被卡住了 - 预处理器肯定不能做数学。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-18
  • 1970-01-01
  • 2012-04-23
  • 1970-01-01
  • 2017-06-29
  • 1970-01-01
相关资源
最近更新 更多