如何阻止 Clang 通过模板过度扩展嵌套循环?

l4m*_*4m2 21 c++ clang compiler-optimization template-meta-programming loop-unrolling

考虑这段代码:

#include <iostream>
typedef long xint;
template<int N>
struct foz {
    template<int i=0>
    static void foo(xint t) {
        for (int j=0; j<10; ++j) {
            foo<i+1> (t+j);
        }
    }
    template<>
    static void foo<N>(xint t) {
        std::cout << t;
    }

};

int main() {
    foz<8>::foo<0>(0);
}
Run Code Online (Sandbox Code Playgroud)

在编译时clang++ -O0,它会在几秒钟内编译然后运行 ​​4 秒。

然而,使用clang++ -O2,编译需要很长的时间和大量的内存。在Compiler Explorer上可以看到,更改8为较小的值后,它完全展开了循环。

我并不是让它完全没有优化,而是让它不递归,就像嵌套循环应该表现的那样。有什么我应该做的吗?

Iwa*_*Iwa 13

可以禁用循环展开优化;请参阅编译器资源管理器。生成的代码是非递归的,并以嵌套循环的形式表示。

#pragma nounroll
for (int j=0; j<10; ++j) {
    foo<i+1> (t+j);
}
Run Code Online (Sandbox Code Playgroud)

您还可以手动调整展开而不是禁用它。按 8 展开会生成与循环 8 次类似的代码。(编译器资源管理器)

#pragma unroll 8
for (int j=0; j<10; ++j) {
    foo<i+1> (t+j);
}
Run Code Online (Sandbox Code Playgroud)