2017-05-18 15 views
3

말 대 내가 무언가 같이있어 이런 일이 컴파일 될 때 후드에서 일어날 것이라고 예상하거나 이렇게 작성하는 것이 더 안전할까요?GLSL 부문은 곱셈

또한 호기심

uniform float invFoo; 
... 
bar = baz * invFoo; 
//instead of: 
uniform float foo; 
... 
bar = baz/foo; 

에 대해 꽤 this을 이해하지 않습니다

// A stupid compiler might use these as written: a divide, then add. 
vec4 result1 = (value/2.0) + 1.0; 
vec4 result2 = (value/2.0) - 1.0; 
vec4 result3 = (value/-2.0) + 1.0; 

// There are most likely converted to a single MAD operation (per line). 
vec4 result1 = (value * 0.5) + 1.0; 
vec4 result2 = (value * 0.5) - 1.0; 
vec4 result3 = (value * -0.5) + 1.0; 

내가 바보 컴파일러는이 상황에서 무엇을하는지 이해가 안 돼요. 이것은 이것이 하나의 MAD 명령으로 행해질 수 있다는 것이 누락 되었는가, 또는 나누기가 곱셈으로 표현 될 수 없다는 것 (동시에 MAD가 누락 됨)이다.

또한, 주변에 물건을 이런 식으로 뭔가를 그룹화하지만 이동에 대해 어떻게 :

vec2 foo,bar; 
float baz; 

baz = 1./baz; 
vec2 temp = vec2(foo.x , bar.x) * baz; //move but do one mult? 
foo.x = temp.x; 
bar.x = temp.y; 

답변

3

은 내가 부문과 마찬가지로 거의 같은 수를 기대할 수 있을까?

은 엄밀히 더, 말하기 없습니다 :

$ cat a.cc 
#include <iostream> 

int main() { 
    const float a = 1.40129846e-45f; 
    const float b = a; 

    std::cout << "b/a:  " << (b/a) << std::endl; 
    std::cout << "b * (1/a): " <<(b * (1.f/a)) << std::endl; 

    return 0; 
} 
$ clang++ a.cc && ./a.out 
b/a:  1 
b * (1/a): inf 
$ 

그러나, 더 많거나 적은 실생활 예제, 곱셈과 나눗셈에 가까운 결과를 제공 할 수 있습니다. 다른 것은 계산의 안정성에 따라 결과를 사용할 것입니다. 이러한 계산이 불안정하면 (즉, 매개 변수가 조금이라도 변경되면 이러한 계산 결과가 크게 변경됨) 결과에 차이가있을 수 있습니다. 따라서 여러분은 여러분이 사용하는 가치와 특히 여러분이 가지고있는 정확성에 대해 알고 있어야합니다. GLSL 부동 소수점은 항상 32 비트 IEEE 부동 소수점 수 있지만 덜 정확할 수 있습니다.

는 이것이이 나눗셈 ( 에서 동일한 시간 MAD 누락)를 곱으로 표현 될 수없는 단일 MAD 명령으로서 수행이거나, 또는 될 수 없습니다.

특정 컴파일러의 특정 단점에 따라 다르지만 아마도 두 번째 것입니다.

+0

답장을 보내 주셔서 감사합니다. MAD 예제에서 안전하기 위해 대부분의 경우에 나눗셈이 추가 된 경우 계산이 불안정하지 않은 경우 역행렬을 계산하고 단일 MAD가 발생할 가능성이있는 곱셈을 수행해야합니다. – pailhead

+0

마지막 코드 스 니펫을 볼 수 있습니까? 방금 업데이트했습니다. – pailhead

+0

@pailhead yep, 그 코드는 아마도 적어도 느리지는 않습니다. 결과가 귀하의 결과에 해가되지 않도록해야합니다. 간단히 시도하고 렌더링 된 이미지의 품질이 변경되지 않았는지 확인하십시오. –