在金属内核中循环展开
Loop unrolling in Metal kernels
我需要强制 Metal 编译器在我的内核计算函数中展开一个循环。到目前为止,我已经尝试将 #pragma unroll(num_times)
放在 for
循环之前,但编译器会忽略该语句。
编译器似乎不会自动展开循环 — 我比较了 1) 带有 for
循环的代码 2) 相同代码但带有手动展开循环的执行时间。手卷版本快3倍
例如:我想从这里开始:
for (int i=0; i<3; i++) {
do_stuff();
}
对此:
do_stuff();
do_stuff();
do_stuff();
Metal C++ 语言中是否有循环展开之类的东西?如果是,我怎样才能让编译器知道我想展开一个循环?
Metal 是 C++11 的子集,您可以尝试使用模板元编程来展开循环。以下是用金属编译的,虽然我没有时间正确测试它:
template <unsigned N> struct unroll {
template<class F>
static void call(F f) {
f();
unroll<N-1>::call(f);
}
};
template <> struct unroll<0u> {
template<class F>
static void call(F f) {}
};
kernel void test() {
unroll<3>::call(do_stuff);
}
如果有效请告诉我!您可能必须向 call
添加一些参数才能将参数传递给 do_stuff
.
另请参阅:
我需要强制 Metal 编译器在我的内核计算函数中展开一个循环。到目前为止,我已经尝试将 #pragma unroll(num_times)
放在 for
循环之前,但编译器会忽略该语句。
编译器似乎不会自动展开循环 — 我比较了 1) 带有 for
循环的代码 2) 相同代码但带有手动展开循环的执行时间。手卷版本快3倍
例如:我想从这里开始:
for (int i=0; i<3; i++) {
do_stuff();
}
对此:
do_stuff();
do_stuff();
do_stuff();
Metal C++ 语言中是否有循环展开之类的东西?如果是,我怎样才能让编译器知道我想展开一个循环?
Metal 是 C++11 的子集,您可以尝试使用模板元编程来展开循环。以下是用金属编译的,虽然我没有时间正确测试它:
template <unsigned N> struct unroll {
template<class F>
static void call(F f) {
f();
unroll<N-1>::call(f);
}
};
template <> struct unroll<0u> {
template<class F>
static void call(F f) {}
};
kernel void test() {
unroll<3>::call(do_stuff);
}
如果有效请告诉我!您可能必须向 call
添加一些参数才能将参数传递给 do_stuff
.
另请参阅: