Math 对绝对值执行max()的最便宜方法,但是否有max()保留符号?

Math 对绝对值执行max()的最便宜方法,但是否有max()保留符号?,math,optimization,comparison,glsl,max,Math,Optimization,Comparison,Glsl,Max,我有一个3向量 v = vec3(-4, 2, 3) 我想对组件的绝对值进行最大化,因此等效于: max(abs(v[0]), max(abs(v[1]), abs(v[2]))) == 4 然而,我有一个要求,我需要保留该标志。例如: magic_max(v[0], magic_max(v[1], v[2])) == -4. 如果我使用条件分支,这是一个很小的问题,但是我尝试用尽可能少的操作来实现这一点,并避免分支。你知道去哪里找吗?也许可以做一些位转移魔法?我会确定所有值的最大值和最小

我有一个3向量

v = vec3(-4, 2, 3)
我想对组件的绝对值进行最大化,因此等效于:

max(abs(v[0]), max(abs(v[1]), abs(v[2]))) == 4
然而,我有一个要求,我需要保留该标志。例如:

magic_max(v[0], magic_max(v[1], v[2])) == -4.

如果我使用条件分支,这是一个很小的问题,但是我尝试用尽可能少的操作来实现这一点,并避免分支。你知道去哪里找吗?也许可以做一些位转移魔法?

我会确定所有值的最大值和最小值,然后决定什么值更大

ma = max(v[0], max(v[1], v[2]));
mi = min(v[0], min(v[1], v[2]));

res = abs(mi) > ma ? mi : ma;
如果要获取标志,请将最后一行替换为If

if (abs(mi) > ma) {
  sign = -1;
  res = mi;
} else {
  sign = +1;
  res = ma;
}

但是,(0,0,0)上应该发生什么?无符号?

我将确定所有值的最大值和最小值,然后决定什么值更大

ma = max(v[0], max(v[1], v[2]));
mi = min(v[0], min(v[1], v[2]));

res = abs(mi) > ma ? mi : ma;
如果要获取标志,请将最后一行替换为If

if (abs(mi) > ma) {
  sign = -1;
  res = mi;
} else {
  sign = +1;
  res = ma;
}

但是,(0,0,0)上应该发生什么?没有迹象?

你不能把这种低级优化留给编译器吗?@BasileStarynkevitch我不相信我的编译器会优化它。这是一个直接进入我的GPU的GLSL字节码编译器,不幸的是,我无法访问任何中间格式(如程序集)来查看它在做什么。如果
vec3(4,0,-4)
?@stefanbachert,你在做什么?幸运的是,输入保证两个组件的绝对值永远不会相等,但这是个好地方。@amoffat:
我不相信我的编译器会优化它。
你担心编译器会浪费一两个周期,而你会手工编写所有东西吗?你会手工写出矩阵乘法、叉积或纹理函数吗?如果不是,为什么这一个案例如此重要以至于你不能让编译器完成它的工作?不,在GLSL中,“位移动”不是你所说的快速<代码>我没有访问任何中间格式的权限来查看它在做什么。如果没有对硬件、调度等方面的深入了解,你就无法判断它是否是最优的。你不能将这种低级优化留给编译器吗?@BasileStarynkevitch我不相信我的编译器会优化它。这是一个直接进入我的GPU的GLSL字节码编译器,不幸的是,我无法访问任何中间格式(如程序集)来查看它在做什么。如果
vec3(4,0,-4)
?@stefanbachert,你在做什么?幸运的是,输入保证两个组件的绝对值永远不会相等,但这是个好地方。@amoffat:
我不相信我的编译器会优化它。
你担心编译器会浪费一两个周期,而你会手工编写所有东西吗?你会手工写出矩阵乘法、叉积或纹理函数吗?如果不是,为什么这一个案例如此重要以至于你不能让编译器完成它的工作?不,在GLSL中,“位移动”不是你所说的快速<代码>我没有访问任何中间格式的权限来查看它在做什么。如果不熟悉硬件、调度等,你就无法判断它是否是最优的。非常聪明。我仍然需要做一个条件来确定最终的有符号值,但我认为这是最好的。谢谢您应该更改if以检查
mi<-ma
否则当
mi=-2**(wordsize-1)
非常聪明时,我们会遇到不必要的问题。我仍然需要做一个条件来确定最终的有符号值,但我认为这是最好的。谢谢您应该更改if以检查
mi<-ma
否则当
mi=-2**(wordsize-1)