【问题标题】:Using functions instead of operators in GLSL / OpenCL?在 GLSL/OpenCL 中使用函数而不是运算符?
【发布时间】:2013-12-08 09:28:58
【问题描述】:

根据我对 C/C++ 编译器的观察,a = b + c;assign(a, add(b, c)); 之间没有任何区别

在其他基于 C 的语言(如 GLSL、OpenCL 等)中进行此类替换是否安全?我正在构建一个代码生成器,我真的很想完全抽象出运算符,并使用良好的旧 C 函数来模拟运算符。

【问题讨论】:

  • 为什么你觉得应该有区别呢?语义是相同的,着色语言中的标量和向量是值类型,因此没有副作用。
  • 我不知道 GLSL 和 OpenCL 的专用编译器如何处理这种操作。他们的内联有多好等等。我不想为“操作员函数”包装器做额外的函数调用,以实现可以用单个机器指令实现的东西。这是我担心的根源。
  • GPU 上没有函数调用(没有堆栈,一切都是静态推导然后内联的 - 一旦不再正确,我希望任何理智的编译器都会内联像这样的微小函数)。所以,不,不会有任何区别,但是你让编译器的生活变得更加困难。如果您有充分的理由(例如代码生成器),那么它可能是值得的,但是请注意,这种语法很快就会变得非常混乱,所以我希望以后没有人需要阅读这些:p
  • 它不是为人眼设计的,实际代码是从可视节点生成的,这是程序员与之交互的。
  • @Thomas - 我有一个额外的问题,考虑到assign() 函数必须通过引用来获取其目标,无论是作为指针还是引用,但是 GLSL 不支持 IIRC ,那么我将如何实际实现这样一个函数,以便它分配给实际成员,而不是作为参数传递的副本?

标签: function operators glsl opencl abstraction


【解决方案1】:

在某些情况下,它可能会编译为相同的代码。可以肯定的是,您确实必须对其进行测试,而我目前知道如何做到这一点的唯一方法是通过glShaderBinary - 在 nvidia 卡上,除了二进制位之外,它还包括一些像纯文本这样的程序集(AFAIK 没有文档这不是 GL 规范所要求的)。

也就是说,我会避免这样做! inout 不会像您预期的那样被编译掉。考虑一下...

int global;

void func(inout int arg)
{
    arg = 1;
    global = 2;
}

void main()
{
    func(global);
    //global now equals 1
}

根据规范(良好的描述here),global 被复制in 到 arg,它被设置为 1。global 被设置为 2,但随后函数返回并且 arg 被复制out,用 1 覆盖 2。

在这种情况下,此操作需要一个额外的寄存器(实际上编译器可能会在这个简单的示例中进行进一步优化),但如果您传递大量数据,您很快就会遇到占用问题(请参阅this)由于副本的额外存储要求。可能还有一些性能开销。复制诸如 done here 之类的数组真的会损害性能。

[编辑]
更安全的选择可能是对所有内容都使用宏...

#define add(a, b) ((a)+(b))
#define assign(a, b) (a = b)

【讨论】:

    猜你喜欢
    • 2012-12-05
    • 2021-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-23
    • 1970-01-01
    • 2017-12-21
    • 2022-08-17
    相关资源
    最近更新 更多