在OpenCL中构造编译时常量的选项?

时间:2015-02-19 03:34:24

标签: opencl

我需要将一堆常量传递给我的OpenCL内核。幸运的是,这些在编译时大多是已知的,意思是:内核编译时。因此,我可以将它们作为一组定义传递给-D leftOuterMargin=3 -D rightOuterMargin=2 -D leftInnerMargin=1 -D rightInnerMargin=2 ...

但这有点笨拙,并且很难在内核中编写可重用的函数。我正在寻找更有条理的东西,比如说结构。但是,结构似乎存储在常量空间中(如果使用全局constant实例创建,可能通过适当的#define)或私有空间(如果在内核函数内创建,也可能通过适当的#存储)定义)?

在内核中构造常量数据有哪些可用选项,这在编译时是已知的?我希望的一些事情:

  • 结构化,可以将一个类似指针的东西传递给可重用的方法,而不是将8-16个名字命名为#defines,或者将8个参数分配到每个非内核方法中
  • 使用时加载的值很快,就像普通的#defined值
  • 一样
  • 编译器可以使用这些值进行优化,例如,如果我使用一个用于循环上限,则该循环可以在编译时完全展开
  • 不会增加注册压力
  • 相对标准,一般可以在不同的gpu平台/制造商上工作

1 个答案:

答案 0 :(得分:1)

此:

  
      
  • 使用时加载的值很快,就像普通的#defined值
  • 一样   
  • 编译器可以使用这些值进行优化,例如,如果我使用一个用于循环上限,则该循环可以在编译时完全展开
  •   
  • 不会增加注册压力
  •   

与此不符:

  
      
  • 可以将一个类似指针的东西传递给每个非内核方法的可重用方法[...]或8个参数
  •   

如果您希望值为常量表达式(换句话说,"编译器已知"),那么唯一的选项是#define和全局 - 范围const。没有通过参数或间接动态传递值。

我建议你用不同的选项制作一个结构:

struct Options {
    int leftOuterMargin;
    int rightOuterMargin;
    int leftInnerMargin;
    int rightInnerMargin;
    // and so on ...
};

然后,您可以定义包含所需常量的所有翻译单元中的标题:

// constants.h

static const Options constants = {
    .leftOuterMargin = 3,
    .rightOuterMargin = 2,
    .leftInnerMargin = 1,
    .rightInnerMargin = 2
};

编译器应该能够像使用#define一样优化代码。