我想改变OpenMP归约子句的语义。 目前,最简单的方法似乎是通过脚本在源代码中替换该子句为函数调用,然后我可以定义该函数以实现我想要的约简语义。 例如,我的脚本会将这个:
#pragma omp parallel for reduction(+:x)
变成这样:
my_reduction(PLUS, &x, sizeof(x));
#pragma omp parallel for
之前,我已经(例如)提到过
enum reduction_op {PLUS, MINUS, TIMES, AND,
OR, BIT_AND, BIT_OR, BIT_XOR, /* ... */};
而且 my_reduction
的签名为
void my_reduction(enum reduction_op op, void * var, size_t size);
除其他事项外,my_reduction
还必须将加法操作应用于减少变量,正如程序员最初打算的那样。但是我的函数无法知道如何正确执行此操作。特别地,尽管它知道操作的类型(PLUS
),原始变量的位置(var
)和变量类型的大小,但它不知道变量的类型本身。具体而言,它不知道 var
是否具有整数或浮点类型。从低级视角来看,这两类类型的加法操作完全不同。
如果只有GCC支持的非标准运算符 typeof
能像 sizeof
一样工作--返回某种类型变量--那么我就可以轻松解决这个问题。但是 typeof 并不像 sizeof 那样:显然,它只能在左值声明中使用。
现在,编译器在完成生成可执行代码之前显然已经知道 x 的类型。这使我想知道是否可以以某种方式利用 GCC 的解析器,仅获取 x
的类型并将其传递给我的脚本,然后再次运行 GCC 来完全编译我的修改后的源代码。然后就可以简单地声明
enum var_type { INT8, UINT8, INT16, UINT16, /* ,..., */ FLOAT, DOUBLE};
void my_reduction(enum reduction_op op, void * var, enum var_type vtype);
而且my_reduction
在解除引用和应用运算符之前可以适当地进行类型转换。
正如您所看到的,我正在尝试在C中创建一种“分派”机制。为什么不使用C++重载?因为我的项目限制了我必须使用用C编写的遗留代码。我可以使用脚本自动更改代码,但我无法将其重写为另一种语言。
谢谢!
reduction({operator|intrinsic_procedure_name}:list)
……从未尝试过内置过程名。虽然它只部分解决了类型检测的问题。 - Bortintrinsic_procedure_name
指的是其他东西。 - Bort