我有一个着色器,我想移动一半的顶点在顶点着色器。我正试图从性能的角度来决定做这件事的最佳方法,因为我们要处理的是100,000多个版本,所以速度是至关重要的。我看了三种不同的方法:(伪代码,但足够给你一个想法。)我不能给出的<complex formula>,但我可以说它涉及一个sin()函数,以及一个函数调用(只返回一个数字,但仍然是一个函数调用),以及一组浮点数的基本算法)。
if (y < 0.5)
{
x += <complex formula>;
}这有一个优点,即<complex formula>只执行一半时间,但缺点是它肯定会导致分支,这实际上可能比公式慢。它是最易读的,但在这种情况下,我们更关心速度而不是可读性。
x += step(y, 0.5) * <complex formula>;使用HLSL的step()函数(如果第一个param更大则返回1),您可以消除分支,但是现在每次都调用<complex formula>,其结果被乘以0(因此浪费了一半时间)。
x += (y < 0.5) ? <complex formula> : 0;这我不知道。?:会导致一个分支吗?如果不是的话,方程的两边是评估的还是只有相关的?
最后一种可能是,<complex formula>可能被卸载回CPU,而不是GPU,但我担心计算sin()和其他操作的速度会变慢,这可能会导致净损失。另外,这意味着还需要将一个数字传递给着色器,这也可能导致开销。有谁能洞察哪一个是最好的行动方针?
增编:
根据http://msdn.microsoft.com/en-us/library/windows/desktop/bb509665%28v=vs.85%29.aspx
step()函数在内部使用?:,因此它可能不会比我的第三个解决方案更好,而且可能更糟,因为<complex formula>肯定是每次都被调用的,而使用直接的?:调用它的时间可能只有一半。(目前还没有人回答这部分问题。)尽管两者都避免,并使用:
x += (1.0 - y) * <complex formula>;很可能比任何一个都好,因为在任何地方都没有比较。( y总是0或1。)仍然有一半的时间执行<complex formula>是不必要的,但是为了完全避免分支,它可能是值得的。
发布于 2015-08-14 17:05:15
我厌倦了我的条件被忽略,所以我只是做了另一个内核,并在c执行中进行了覆盖。如果你总是想要准确的话,我建议你解决这个问题。
https://stackoverflow.com/questions/12460649
复制相似问题