이것이 뭐냐하면 퀘이크 3 소스코드에 있는 함수다
정확히는 를 계산하는 함수인데, 광원 효과에 쓰이는 함수라서 굉장히 빨라야 한다
(빛의 반사 계산하는 데 쓰는데, 단위벡터가 어쩌구 반사벡터가 저쩌구 하는 건 생략)
중요한 건 느리면 60 프레임을 못맞추고, 빨라도 값의 정확하지 않으면 빛이 이상하게 표현된다
나눗셈이랑 제곱근을 쓰는 방법은 정확한 대신 리소스도 많이 필요하고 줜나 느려서 60프레임을 못맞춘다
그래서 퀘이크 3 개발진은 저런 함수를 만들어 를 빠르고 정확하게 계산했다
일단 보면 주석에 왓더뻑이라고 적힌 것처럼 씨1발 이게 뭐야 어캐 하는건데 싶어진다
그래도 하나 하나 뜯어보면 이해가 되긴 된다
우선 맨 앞에 변수의 자료형 두 개가 나온다
long은 숫자를 이진법으로 00000000 00000000 00000000 00000000으로 표시한다
long형에서 특별히 봐야할 건 없으니 넘어가자
float은 소숫점을 포함한 실수를 0 00000000 00000000000000000000000으로 표현한다
첫 자리는 부호를 나타낸다
0이면 양수 또는 0, 1이면 음수를 뜻한다
뒤의 8자리는 지수(2E)를 나타낸다
E = -127를 00000000으로 하고 E = +128을 11111111로 사용한다
마지막 23자리는 가수부(M)를 나타낸다
이진법으로 1.00000000000000000000000부터 1.11111111111111111111111까지 소숫점을 나타내는 데 사용한다
float형을 수식으로 표현하면 이런 꼴이 된다
뜬금없이 나온 뮤(μ)는 log2의 근사값을 구하는 데 쓰인 숫자다
1보다 작은 x에 대해 인데 적당한 수를 더하면(
) 전반적인 정확도를 높일 수 있다
실험적으로 찾아낸 적절한 값은 μ≒0.0430357이다
그런데 float형의 비트값은 E*223 + M 꼴의 형태가 되는 것을 알고 있다
(여기서 음수는 생각하지 않는다)
앞에서 구한 로그값이랑 비교하여 생각해보면 float형의 비트값을 그대로 하나의 정수로 생각하면 이 정수는 원래 값에 log2를 취한 것과 같다고 생각할 수 있다
변수 정의 뒤에 나오는 i = * ( long * ) &y; 가 바로 float형으로 받은 비트값을 그대로 숫자로 받는 줄인 것이다
어찌저찌하여 중간까지는 왔는데 그 다음 줄이 문제다
앞서 였고
를 구해야 하는데, 로그의 특성에 따라
가 된다!
그리고 이진수에서 오른쪽으로 비트를 이동(bit shift)하면 2로 나눈 것과 같은 효과를 얻는다
예를 들어 110(10진법으로 6)을 오른쪽으로 비트 이동시키면 11(10진법으로 3)이 된다
111(10진법으로 7)도 11(10진법으로 3)이 되는 문제가 있지만 어쩔 수 없이 받아들여야 한다
오른쪽으로 비트 이동이 >>니까 -0.5i는 -(i >> 1)이 된다
그러면 저 0x5f3759df(=1597463040)는 대체 뭔 수일까?
실제로 구해야 하는 해 를 감마(Γ)라고 하면 i와 Γ의 관계는 다음과 같다
정리하면,
값을 계산하면, 3/2 * 223 * (127-μ) = 1597488309.57 ≒1597463040 = 0x5f3759df
그렇다, 오차를 보정하는 값이 바로 저 0x5f3759df였던 거다!
값을 다 구했으니 구한 값을 float형으로 되돌리고 → y = * (float *) &i;
f(x) = 0을 정확하게 구할 때 쓰는 뉴턴-랩슨법을 이용해 정확도를 높여주면 → y = y * (threehalfs - (x2 * y * y));
그리하여 나눗셈도, 제곱근 계산도 없이 포인트 참조, 비트 이동, 뺄셈, 그리고 곱하기만 가지고 빠르고 비교적 정확하게 를 구할 수 있었다!
(IP보기클릭)106.102.***.***
더 충격적인건 요즘은 더 효율좋은 알고리즘을 쓰고잇음
(IP보기클릭)222.118.***.***
요즘은 그냥 FPU가 더 빠르다.. 그냥 표준 함수인 sqrt를 쓰면 된다..
(IP보기클릭)211.234.***.***
음. 고대언어로 쓰인 미법진이군.
(IP보기클릭)175.112.***.***
(IP보기클릭)14.35.***.***
자료형식을 바꾸고 곱셈 뺄셈 좀 하는걸로 1/sqrt 값을 구해내는게 정상이냐아아아아아아악
(IP보기클릭)175.195.***.***
3줄 요약좀
(IP보기클릭)119.71.***.***
그, 그렇군!
(IP보기클릭)175.112.***.***
(IP보기클릭)211.234.***.***
음. 고대언어로 쓰인 미법진이군.
(IP보기클릭)106.102.***.***
더 충격적인건 요즘은 더 효율좋은 알고리즘을 쓰고잇음
(IP보기클릭)222.118.***.***
불량닉네임은 계정징계조치
요즘은 그냥 FPU가 더 빠르다.. 그냥 표준 함수인 sqrt를 쓰면 된다.. | 25.06.28 11:50 | | |
(IP보기클릭)218.154.***.***
대충 찾아보니까 요즘은 그냥 하드웨어에서 지원을 하네 | 25.06.28 11:53 | | |
(IP보기클릭)211.234.***.***
왠만한 수식은 이미 라이브러리화 되긴 했지 이 수식들로 뭔가를 할때 리소스 덜 먹도록 알고리즘을 짜는게 요즘식 최적화고 | 25.06.28 11:58 | | |
(IP보기클릭)175.195.***.***
3줄 요약좀
(IP보기클릭)61.84.***.***
퀘이크 3에서 개쩌는 코드가 있음 삼줄 | 25.06.28 11:52 | | |
(IP보기클릭)222.118.***.***
유명한 빠르게 제곱근 구하는 알고리즘이야.. 퀘이크3 소스에 들어있어.. | 25.06.28 11:54 | | |
(IP보기클릭)222.235.***.***
졸트라크 | 25.06.28 11:59 | | |
(IP보기클릭)96.231.***.***
아주 쉽게 설명하면.. 컴퓨터 프로그램이 졸라 짱짱맨인 것 같아도... 의외로 수학적인 계산할 때 비교적 리소스를 많이 먹는데...(특히 소수점있는) 졸라 빡센 계산해야 나오는 값을.. 아주 쉽게 비트단위 이동으로 대신하는 개간결한 코드를 만들었다는거임. 아주 쉬운 예를 들면 2진법에서.. 1이 한칸씩 올라가면(1을 옆으로 밀면) 00000001 -> 00000010 -> 00000100 이렇게 한칸씩 밀면 2를 곱하는 것과 같은 결과인데.. A x 2를 연산하는것보다.. 비트를 한칸씩 옮기는 작업이 굳이 둘을 비교했을 때 속도면에서 엄청 빠르다는거임. | 25.06.28 12:12 | | |
(IP보기클릭)211.243.***.***
(IP보기클릭)211.245.***.***
(IP보기클릭)14.35.***.***
자료형식을 바꾸고 곱셈 뺄셈 좀 하는걸로 1/sqrt 값을 구해내는게 정상이냐아아아아아아악
(IP보기클릭)119.71.***.***
그, 그렇군!
(IP보기클릭)122.40.***.***
(IP보기클릭)125.180.***.***
(IP보기클릭)223.39.***.***
(IP보기클릭)119.192.***.***
(IP보기클릭)61.72.***.***
(IP보기클릭)106.101.***.***
(IP보기클릭)112.157.***.***
(IP보기클릭)211.234.***.***
(IP보기클릭)175.196.***.***
제약속에서 빛나던 이들이 어느샌가부터 느그컴업글하면되잖? 하던 애들만 남았어ᆢ 코딩깎던 노인이 그립다 | 25.06.28 12:02 | | |
(IP보기클릭)106.101.***.***
엔진만드는 급이면 그거 계속할수 있음 뭐 되도않는 루프 줄이기 이런거 말고 요즘은 컴파일러가 알아서 최적화도 잘함 | 25.06.28 12:05 | | |
(IP보기클릭)211.234.***.***
옛날은 사람 몸값보다 하드웨어가 비싸서 사람 갈아 최적화하는게 비용절감에 도움이 되던 시대였는데 요즘은 사람 몸값이 하드웨어보다 비싼 시대가 되버려서, 최적화보다 일정 줄이는게 전체 비용절감에 더 도움이 되는 시대가 되버림... | 25.06.28 12:07 | | |
(IP보기클릭)183.101.***.***
(IP보기클릭)58.224.***.***
(IP보기클릭)175.197.***.***
조무사가 왜 ㅜㅜ | 25.06.28 11:58 | | |
(IP보기클릭)118.235.***.***
조무사드립 쓰지 말자.. | 25.06.28 12:08 | | |
(IP보기클릭)121.147.***.***
(IP보기클릭)59.13.***.***
(IP보기클릭)182.229.***.***
(IP보기클릭)118.235.***.***
수상한 애니프사 중국인 ㅋㅋㅋㅋ | 25.06.28 12:02 | | |
(IP보기클릭)121.144.***.***
근데 진짜 깃에 애니프사인데 핵고수들 있음 ㅋㅋ | 25.06.28 12:07 | | |
(IP보기클릭)118.235.***.***
(IP보기클릭)211.234.***.***
프로그래머들 특히 2000년 즈음엔 프로그래머중 진짜 천재적으로 수학을 다루는 사람이 꽤 많았지 | 25.06.28 12:02 | | |
(IP보기클릭)87.249.***.***
애초에 IEEE에서 부동 실수형을 설계할 때부터 저렇게 수학적으로 작동하기 쉽게 해 준 덕분이지! | 25.06.28 12:04 | | |
(IP보기클릭)211.234.***.***
(IP보기클릭)118.235.***.***
(IP보기클릭)175.114.***.***
(IP보기클릭)87.249.***.***
근사값임. 애초에 엄청나게 정확할 필요도 없음 | 25.06.28 12:07 | | |
(IP보기클릭)220.119.***.***
근사값 구하는 거래 지금은 하드웨어 수준에서 더 정확한 걸 기본 탑재하고 있다는 듯 | 25.06.28 12:07 | | |
(IP보기클릭)87.249.***.***
저 맨 아래줄 반복을 여러번 하면 정확한 값에 수렴하긴 함 | 25.06.28 12:07 | | |
(IP보기클릭)112.148.***.***
빠르게 근사값을 구하는거. 컴퓨터는 이진법이라 어차피 정확한 값을 요구하진 않으니 그걸 이용해서, 사용자한테 빠르게 계산결과값을 제공하기 위한 피나는 노력. | 25.06.28 12:08 | | |
(IP보기클릭)119.197.***.***
(IP보기클릭)58.224.***.***
아하 코드복붙이구나! | 25.06.28 13:20 | | |
(IP보기클릭)112.148.***.***
(IP보기클릭)222.235.***.***