sqrt 나 log 를 카멕's hack 이나 테일러급수로 최적화하는것 따윈 내장 명령어 앞에 허무하게 무너졌고
비트 연산자를 이용한 곱셈 나눗셈 최적화도 펜티엄 이후 무의미.
임베디드엔 가끔 쓸모 있는 경우도 있겠지만.
그래도 아직까지 꽤 유용한 기법은 부동소수점 트릭이다.
float a, b, c;
a = some_value;
b = some_value;
c = fabs(a - b);
이런 경우.
혹자는 이렇게 한다.
c = a - b;
if (c < 0) c = -c;
(함수 호출을 줄였다)
혹자는 이렇게도 한다.
c = a - b;
if (a < b) c = b - a;
(계산 결과가 c 에 반영되는걸 기다리지 않게 파이프라인 최적화)
그래도 약해.
c = a - b;
*(int*)&c &= 0x7FFFFFFF;
이게 정답.
속도는 2배 이상이라고 봐도 됨.
위의 코드들과는 좀 별도로
if (a - b < 0 && c - d < 0) e++;
이런 경우도
ab = a - b;
cd = c - d;
e += (*(unsigned int*)&ab >> 31) & (*(unsigned int*)&cd >> 31);
로 처리하면 처리 속도 급상승.
SIMD 랑 같이 쓰기는 별롤것 같아.
(예문을 작성하고 보니 딱 적절한 예는 아니넹. 뭐 이런 방법도 있다공. bitwise operator 죄다 활용할 수 있음)
한마디로 코세 성님은 32비트 정수 x에 대해서 x & 0x7FFFFFFF를 하면 절대값이 나온다고 생각하시는 건가요? 안 그러는데요...ㄷㄷ 2의 보수를 고려하면...
아니 부동소수 이야기야.
부동소수엔 비트연산을 못쓰니 잠시 int 인것처럼 속여서 계산하는거지.
아아. int만 보고 잠깐 제가 헛소리를 했네요. 그렇죠 ㅋㅋ sign 비트만 바꿔주면 부호 바꿀 수 있다는 건 정말 편한 거 같아요.
정수면 저 짓을 왜하겠어 충분히 빠른데 ㅋ
코드에 살짝 오류가 있지만 뭐... 어차피 pseudo code 수준이니까 저걸 이해 못하는 사람은 없겠죠. int 형을 float에 대입하셔서 ㅋㅋㅋ
아 쏘리~
*(int *)&c &= 0x7FFFFFFF; 라고 하셔야 될 거 같아요.
마자마자
쫄따구가 만든 이미지 필터 최적화 하다가 500msec 걸리던거 200msec 까지 줄일 수 있다고 했는뎅, 250까지 밖에 안주는거양. 그래서 낑낑대다 저방법을 써서 171msec 만듦. 헤헷.
캬... 사스가... 근데 성님 왜 fabs는 내부적으로 저 방법을 쓰지 않은 걸까요? 그냥 FPU register에 넣고 빼느라 걸린 delay 때문인가...
컴파일러랑 c 기본 라이브러리 만드는애들이 부지런하면 우리 월급 줄어.
ㅋㅋㅋㅋ 혹시 어셈의 FABS 명령어(있는지는 모르겠는데요)보다도 빠를까요?
농담이고. 결국 simd 를 쓸거면, 아직은 float & double 과 int 간의 연산이 바뀔때 오버헤드가 있는걸로 아니까 (테스트 해 본게 몇 년 전인지) 저 방법이 항상 답이진 않지. 그냥 C/C++ 로 짠다면 충분히 유효한 정도 : )
FPU 명령군에 FABS 있네요. 음... 궁금하네요 ㅋ
있긴한데 결국 FP 스택에 넣어서 처리하는거라... 느릴껄...
fld fabs fstp 해야 될거야. 엿같아.
저방법은 정수 실수간 계산도 정수 정수간 계산으로 바꿔줄 수 있는 가능성이 있으니 : )
하아... FABS FLOAT PTR [xxx] 이런 게 지원된다면 좋을텐데요...;;
FLD/FSTP 빼고 FABS만 놓고 보면 속도가 어떨까요?
인텔 애들도 내부적으로 FABS 명령을 하드웨어적으로 구현할 때 Sign bit만 zero로 clear하는 쪽으로 구현했겠죠? 더 복잡하게 구현하는 게 회로가 복잡해질테니...
건 궁금하긴 하네 : ) 그래도 정수 &= 상수 인데 저방법이 느릴리가?
만약 그렇다면 결국 문제는 FLD/FSTP로 인한 integer <-> floating point 간의 변환 및 FPU register와 RAM 간의 전송에 따른 오버헤드가 핵심이겠군요.
어차피 실존하지 않는 가정이니까 게으른 나는 테스트는 안해볼래 : )
글구 측정도 쉽지않겠다야..
ㅋㅋㅋ 私も後で暇な時に試すんです
단순히 fabs 도배해서 클럭 재는건 좀 : )
그냥 10000번 정도 돌려서 QueryPerformanceCounter 가지고 측정하는데, FLD/FABS/FSTP 전부 한 거 - FLD/FSTP만 한 거 랑 &= 한 거 비교하면 되겠네요 :)
그정도로 한가한때가 안온다에 한 표.
루프 돌면 안되징. 어차피 정수 연산 개입되면 부동소수점 연산 오버헤드 계산할때 노이즈임.
그러면 *10000개로 갈게요 ㅋㅋㅋ
그리고 캐시에 의한 최적화도 있을 수 있으니 적당히 주소 바꿔가며 해야 될 거 같아요
아 그건 정수일 때도 마찬가질테니 상관없겠구나...
아무튼 FABS랑 AND [xxx], 7FFFFFFFh 간의 성능 차는 은근히 궁금하네요 ㅋㅋㅋ 이런 hardware-specific한 건 빠져봐야 의미가 없는데 궁금한 건 어쩔 수 없어요 ㅋㅋ geek스러운...
ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ
그래도 문제가 있다.
파이프라인은 어떡할려구
앜ㅋㅋㅋㅋㅋㅋ 파이프라인은 무시해야 하지 않을까요 그거까지는 진짜 ㅋㅋㅋㅋㅋ 매너점 ㅋㅋㅋ
오예~ 간만에 무분기 코드다~ 하고 CPU가 파이프라인에 집어넣으려다가 fabs 가 반복되면 어라 rvalue 종속케이스네 하고 당황하겠지? ㅋㅋ
그렇게 따지면 저거 테스트하려면 Windows 상이 아니라 Boot Loader에 프로그램 넣어서 테스트해야 한다는 결론이 나욬ㅋㅋ
결국 제대로 된 성능측정이 힘들듯. fld 가 필수라.
앜ㅋㅋㅋㅋ 그러네요ㅋㅋㅋㅋㅋ
fld 와 fabs fstp 는 atomic 하다고 보는데 맞아.
파이프라인을 따져야 한다면 Task Switching이랑 Multiprocessor 문제도 있어서 Windows 상에서 테스트해도 안되죠 ㅋㅋ 윗 덧글은 그런 의미였어요 ㅋㅋㅋ
아니 돼.
스위칭 타임셀이 조밀하지 않아서 돼 : )
음... Task Switching은 그렇게 영향을 안 준다고 생각하시는 건가요?
아하...
performance profiler 들이 달리 있는게 아니징.
보는데가 아니라 보는게 ㅡㅡㅋ 다시 읽어봄.
거물들의 대화