着色器的功能参数性能 [英] Shader's function parameters performance

查看:206
本文介绍了着色器的功能参数性能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图了解如何以着色器语言实现传递参数.

I'm trying to understand how passing parameters is implemented in shader languages.

我已经阅读了几篇文章和文档,但仍然有一些疑问.特别是,我试图通过C++函数调用来理解这些差异,并特别强调性能.

I've read several articles and documentation, but still I have some doubts. In particular I'm trying to understand the differences with a C++ function call, with a particular emphasis on performances.

HSLS,CgGLSL之间有些细微的差别,但是我认为下划线的实现非常相似.

There are slightly differences between HSLS,Cg and GLSL but I guess the underline implementation is quite similar.

到目前为止我所了解的:

What I've understood so far:

  • 除非另行指定,否则函数参数始终通过值传递(即使对于矩阵也是如此)
  • 在这种情况下按值传递与C++的含义不同.不支持递归,因此不使用堆栈,并且内联大多数函数,并将参数直接放入寄存器.
  • 函数通常默认情况下是内联的(HLSL),或者至少始终是编译器尊重的内联关键字(Cg)
  • Unless otherwise specified a function parameter is always passed by value (is this true even for matrix?)
  • Passing by value in this context hasn't the same implications as with C++. No recursion is supported, so the stack isn't used and most function are inlined and arguments directly put into registers.
  • functions are often inlined by default (HLSL) or at least inline keyword is always respected by the compiler (Cg)

以上考虑因素是否正确?

Are the considerations above right?

现在有2个具体问题:

1)将矩阵作为函数参数传递

inline float4 DoSomething(in Mat4x4 mat, in float3 vec)
{
  ...
} 

考虑到上述功能,在C++中这很讨厌,并且使用引用const Mat4x4&绝对更好.

Considering the function above, in C++ that would be nasty and would be definitely better to use references : const Mat4x4&.

着色器呢?这是一个不好的方法吗?我读到例如inout限定符可用于通过引用传递矩阵,但实际上它暗示该矩阵可以由调用的函数进行修改..

What about shaders? Is this a bad approach? I read that for example inout qualifier could be used to pass a matrix by reference, but actually it implicates that matrix be modified by the called function..

2)数字(和参数类型)有什么含义吗?例如,更好地使用带有有限参数集的函数还是避免传递矩阵? inout修饰符在这里是提高性能的有效方法吗?如果是这样,没有人知道典型的编译器是如何实现的吗?

2) Does the number (and type of arguments) have any implication? For example is better use functions with a limited set of arguments?Or avoid passing matrices? Is inout modifier a valid way to improve performance here? If so, anyone does know how a typical compiler implement this?

3)在HLSLGLSL之间有什么区别吗? 有人对此有提示吗?

3) Are there any difference between HLSL an GLSL on this? Does anyone have hints on this?

推荐答案

根据规范,总是复制值.对于in参数,它们在调用时被复制,对于out参数在返回时被复制,对于inout参数在调用和返回时都被复制.

According to the spec, values are always copied. For in parameters, the are copied at call time, for out parameters at return time, and for inout parameters at both call and return time.

使用规范的语言(GLSL 4.50,第6.1.1节函数调用约定"):

In the language of the spec (GLSL 4.50, section 6.1.1 "Function Calling Conventions"):

所有参数在调用时均按从左到右的顺序进行一次赋值.输入参数的求值结果将被复制到形式参数中.对out参数的求值将生成一个l值,该l值用于在函数返回时复制出一个值.评估inout参数会同时产生一个值和一个l值;该值在调用时被复制到形式参数中,而左值用于在函数返回时复制出一个值.

All arguments are evaluated at call time, exactly once, in order, from left to right. Evaluation of an in parameter results in a value that is copied to the formal parameter. Evaluation of an out parameter results in an l-value that is used to copy out a value when the function returns. Evaluation of an inout parameter results in both a value and an l-value; the value is copied to the formal parameter at call time and the lvalue is used to copy out a value when the function returns.

一个实现当然可以自由地优化它想要的任何东西,只要结果与所记录的行为相同即可.但是我认为您不能指望它能以任何指定的方式工作.

An implementation is of course free to optimize anything it wants as long as the result is the same as it would be with the documented behavior. But I don't think you can expect it to work in any specify way.

例如,通过引用传递所有inout参数将不会被保存.假设您有以下代码:

For example, it wouldn't be save to pass all inout parameters by reference. Say if you had this code:

vec4 Foo(inout mat4 mat1, inout mat4 mat2) {
    mat1 = mat4(0.0);
    mat2 = mat4(1.0);
    return mat1 * vec4(1.0);
}

mat4 myMat;
vec4 res = Foo(myMat, myMat);

对此的正确结果是包含所有0.0分量的向量. 如果参数是通过引用传递的,则Foo()中的mat1mat2将为相同的矩阵别名.这意味着对mat2的赋值也会更改mat1的值,结果是包含所有1.0分量的向量.哪有错.

The correct result for this is a vector containing all 0.0 components. If the arguments were passed by reference, mat1 and mat2 inside Foo() would alias the same matrix. This means that the assignment to mat2 also changes the value of mat1, and the result is a vector with all 1.0 components. Which would be wrong.

这当然是一个非常人为的示例,但是优化必须是选择性的,以便在所有情况下都能正常工作.

This is of course a very artificial example, but the optimization has to be selective to work correctly in all cases.

这篇关于着色器的功能参数性能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆