我有一些C函数,除其他外,它执行模运算。所以它看起来像
const int M = 641;
void func( ...parameters..) {
int x;
... some operations ...
x %= M;
... some more operations ...
}
现在,对我来说至关重要的是,这里的数字M是一个常数。如果我不告诉编译器M是常量,那么我的性能会慢得多。
目前,我对我的函数func(..)非常满意,我想扩展它,所以它可以在不同的模块上工作。但同样重要的是,这些模量是固定的。所以我希望能够做到像
这样的事情const int arrayM[] = {641, 31, 75, 81, 123};
然后为常量数组array_M[i]
中的每个索引提供函数func的一个版本,比如func_i,它是函数func的副本,但array_M[i]
替换M
的角色{1}}。
在实践中,我的常量数组arrayM[]
将由大约600个显式素数组成,我将以特定方式选择,以便x % array_M[i]
编译为非常快速的模数函数(例如Mersenne素数)。
我的问题是:如何在C中执行此操作而不制作600个函数函数副本,并且每次更改代码中的变量M?
最后,我想再次针对CUDA代码提出同样的问题。所以,如果我有一个cuda-kernel,那么在代码的某个点上执行模M
运算,并且我想拥有相同内核的不同副本(每个{{1}的索引一个})。
答案 0 :(得分:3)
您可以使用以下定义:
#define F(i,n) void func_##i() { printf("%d\n",n); }
#include <stdio.h>
F(1,641)
F(2,31)
...
int main() {
func_1();
func_2();
}
可以从常量列表中获得相同的效果,但它更加棘手。请参阅recursive macro。
答案 1 :(得分:1)
大多数编译器都会进行持续传播。您需要将优化级别调高。然而,唯一可以确定的方法是检查汇编代码,或者用折叠的常量显式地编写代码,这很难看并且难以维护。 C ++允许您将标量指定为模板。