![]() |
|
||||||||
경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지 |
|
같은 8byte 끼리의 연산이라도, double은 CPU에서 한방에 연산하는 명령어를 제공하기때문에 속도는 같습니다.
우리가 실제 느끼는 속도는 CPU 내부의 micro operation 이 이뤄지는 명령어 수가 아니라 CPU가 제공하는 외부인터페이스의 명령어 수이기 때문에요... 실제 내부에선 얼마가 걸리더라도 외부에는 cpu의 시간단위인 "클럭" 단위 이하의 시간은 존재하지 않으니까요... 그쪽까진잘 모르지만, 아마 실제 계산량은 4byte 쪽이 적을지도 모르죠... 하지만 결국 우리에게 공개된 명령어에선 double 이나 int 연산이나 같은 클럭을 소모하는 명령어라는거죠. 예외적으로.. int64형 같은 경우 32bit에서 int64형 연산을 위한 명령어를 제공하지 않으므로, 32bit 2개로 분해해서 연산하는 과정을 거칩니다. 그래서 느리죠... 물론 64bit os라면 상관없겠지만. Lyn님의 말씀은 대부분의 연산이 하나의 intruction으로 제공된다는 것이고요, 하지만 하나의 instruction이 1CLK으로 처리되는 것은 아닙니다. 각 instruction 마다 사용하는 CLK의 수가 정해져(?)있습니다. 단순 MOV와 MULPD처럼 복잡한 연산이 같은 CLK내에 처리된다면 좀 불공평하지 않겠습니까?
다만 요즘의 CPU에서는 하나의 instruction이 모든 상황에서 동일한 스피드(CLK아님)로 수행되는 것은 아닙니다. 왜냐면 파이프라인이나 슈퍼스칼라와 같은 방법으로 병렬로 instruction이 처리되기 때문입니다. 옛날 92년도에 봤던 어셈블러 책에서는 x86의 각 instruction당 사용하는 CLK의 수가 명시되어 있어서 그 CLK으로 실제 동작하는 시간을 계산하곤 했습니다. 하지만 방금 Intel의 IA32 instruction manual을 뒤져봤는데 CLK수를 명시해 놓지 않았네요. 어쨋든 대략적인 속도는 계산 가능하나 실제 만들어지는 코드(machine instruction)의 연관된 순서에 따라 실제 속도는 달라질 수 있습니다. 또하나는 code optimization에 따라서도 속도차이가 납니다. 아시다시피 register연산이 훨씬 빠르고요, 요즘 나오는 CPU(IA기준)는 instruction에 따라 메모리에서 직접 연산하는 instruction들도 많이 있습니다. 따라서 어떤 instruction code로 바이너리가 만들어지는 지에 따라서도 미묘한 차이를 보입니다. 참고하시기 바랍니다. 1. 테스트 코드의 작성요령은 __int64 getRDTSC() { asm rdtsc; } 처럼 클럭틱을 리턴받을 함수를 통해 앞뒤로 코드를 싼다
2. 테스트할 코드는 적어도 10번 정도 순서대로 늘어쓴다. (for문은 따로 클럭수를 계산해야 되니 귀찮고 사실 RDTSC는 한번의 실행도 거의 정확하게 잡아내긴 하죠) 3. 테스트에 사용될 변수들은 미리 double temp = ia * ib * fa * fb * da * db .... 처럼 해서 다 캐싱시켜버린다. 4. 적어도 곱셈은 일정하다고 주장하셨으니 ia = 1, ib = 2 처럼 초기화 해 놓은 상태에서 ia *= ib 를 열번쯤 한다. 5. 처리의 누적 결과인 (ex) ia, fa, da ... 들은 반드시 어딘가의 유효한 rvalue로 사용한다. (최적화에서 걸러지는 것 방지) (ex. Caption = ia * fa * da ...) 6. 테스트는 반드시 release 모드로 한다. 7. 모든 처리결과 시간은 미리 선언해둔 __int64 변수에 저장해 뒀다가 모든 처리가 끝난 후 Visual Component등에서 표시한다. 이렇게 하시면 보다 정확한 결과를 얻을 수 있습니다. __int64 getRDTSC() { asm rdtsc; }
void __fastcall TForm1::Button1Click(TObject *Sender) { __int64 begin, d1, d2, d3, d4, d5; int ia = 1, ib = 2; float fa = 1, fb = 2; double da = 1, db = 2; int ifa = 1; float ifb = 2; double dfa = 1; float dfb = 2; double temp = ia * ib * fa * fb * da * db * ifa * ifb * dfa * dfb; begin = getRDTSC(); ia *= ib; ia *= ib; ia *= ib; ia *= ib; ia *= ib; ia *= ib; ia *= ib; ia *= ib; ia *= ib; ia *= ib; d1 = getRDTSC() - begin; begin = getRDTSC(); ifa *= ifb; ifa *= ifb; ifa *= ifb; ifa *= ifb; ifa *= ifb; ifa *= ifb; ifa *= ifb; ifa *= ifb; ifa *= ifb; ifa *= ifb; d2 = getRDTSC() - begin; begin = getRDTSC(); fa *= fb; fa *= fb; fa *= fb; fa *= fb; fa *= fb; fa *= fb; fa *= fb; fa *= fb; fa *= fb; fa *= fb; d3 = getRDTSC() - begin; begin = getRDTSC(); dfa *= dfb; dfa *= dfb; dfa *= dfb; dfa *= dfb; dfa *= dfb; dfa *= dfb; dfa *= dfb; dfa *= dfb; dfa *= dfb; dfa *= dfb; d4 = getRDTSC() - begin; begin = getRDTSC(); da *= db; da *= db; da *= db; da *= db; da *= db; da *= db; da *= db; da *= db; da *= db; da *= db; d5 = getRDTSC() - begin; Caption = ia * fa * da * ifa * dfa; Memo1->Lines->Add(""); Memo1->Lines->Add(d1); Memo1->Lines->Add(d2); Memo1->Lines->Add(d3); Memo1->Lines->Add(d4); Memo1->Lines->Add(d5); } 관련 글 리스트
|
Copyright © 1999-2015, borlandforum.com. All right reserved. |
이유는?
찍었음. ㅋㅋ