빠른 1/sqrt(n) 계산방법

2014.03.05 03:43

단장 조회 수:412

http://en.wikipedia.org/wiki/Fast_inverse_square_root


사실 애니메이션 본TM계산시 엄청나게 많이 쓰는데 당연한 얘기지만 각종 노말라이즈에 다 들어가는 수식이기 때문이가.

그런데 생각보다 속도가 느리다... 이를 최적화하는 기법. 


최초 구현된 것은 ID의 Quake 3 Arena에서 존카멕 형이 만든 것. 아래의 소스 코드이다.


float Q_rsqrt( float number )
{
	long i;
	float x2, y;
	const float threehalfs = 1.5F;
 
	x2 = number * 0.5F;
	y  = number;
	i  = * ( long * ) &y;                       // evil floating point bit level hacking
	i  = 0x5f3759df - ( i >> 1 );               // what the fuck?
	y  = * ( float * ) &i;
	y  = y * ( threehalfs - ( x2 * y * y ) );   // 1st iteration
//      y  = y * ( threehalfs - ( x2 * y * y ) );   // 2nd iteration, this can be removed
 
	return y;
}



아래는 언리얼4엔진에서 사용하고 있는 방법. SSE 를 사용하고 있다.


static FORCEINLINE float InvSqrt( float F )

{

static const __m128 fThree = _mm_set_ss( 3.0f );

static const __m128 fOneHalf = _mm_set_ss( 0.5f );

__m128 Y0, X0, Temp;

float temp;


Y0 = _mm_set_ss( F );

X0 = _mm_rsqrt_ss( Y0 ); // 1/sqrt estimate (12 bits)


// Newton-Raphson iteration (X1 = 0.5*X0*(3-(Y*X0)*X0))

Temp = _mm_mul_ss( _mm_mul_ss(Y0, X0), X0 ); // (Y*X0)*X0

Temp = _mm_sub_ss( fThree, Temp ); // (3-(Y*X0)*X0)

Temp = _mm_mul_ss( X0, Temp ); // X0*(3-(Y*X0)*X0)

Temp = _mm_mul_ss( fOneHalf, Temp ); // 0.5*X0*(3-(Y*X0)*X0)

_mm_store_ss( &temp, Temp );


return temp;

}



댓글 0

파일 첨부

여기에 파일을 끌어 놓거나 파일 첨부 버튼을 클릭하세요.

파일 크기 제한 : 0MB (허용 확장자 : *.*)

0개 첨부 됨 ( / )
 
목록
번호 제목 글쓴이 날짜 조회 수
64 문길 설치법 단장 2017.04.19 20
63 진 여신전생 스트레인지 저니 에디터 코드 단장 2015.06.18 143
62 VC 2012이후에서 릴리즈 빌드 스택변수들 디버깅하기 file 단장 2014.03.05 217
61 Large Address Aware file 단장 2014.03.05 619
» 빠른 1/sqrt(n) 계산방법 단장 2014.03.05 412
59 마포에서 AF되는 포서드용 렌즈들 단장 2014.02.13 180
58 디카 이미지 슬라이드필름처럼 보정하기 file 단장 2014.02.13 156
57 비디오 카드의 정의 단장 2013.11.30 167
56 Windows 8.1 복구 파티션 만들기 단장 2013.11.13 6094
55 마력 구하는 공식 단장 2013.07.11 1152
54 [공지] 게시판 용도 김도완 2005.06.16 1094
53 Stream of Life 단장 2009.06.29 1152
52 골프의 물리학 단장 2009.05.30 1549
51 Fast Bit Counting 단장 2009.02.21 1606
50 vTune 사용법 단장 2009.01.13 1237
49 제트 추력 엔진 단장 2008.04.29 1440
48 std::tr1 단장 2008.03.13 1310
47 일본어 날짜 단장 2008.02.19 1132
46 Networking Best Practices in XBOX360 단장 2007.12.19 1486
45 개인적으로 만들어 본 리눅스 게임 서버 FAQ 단장 2007.11.27 1108