C++Builder Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
C++빌더 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
컴포넌트/라이브러리
메신저 프로젝트
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
볼랜드포럼 광고 모집

C++빌더 팁&트릭
C++Builder Programming Tip&Tricks
[962] [퀴즈] 다음 계산중 어느게 속도가 빠를까요?
장성호 [nasilso] 12292 읽음    2010-03-12 00:00
32bit pc에서
다음 5가지 계산중 어느게 속도가 빠를까요?
순서대로 나열해 보세요.

1. int * int
2. int * float
3. float * float
4. double * float
5. double * double



사실 저도 정확히 잘 모르는 문제입니다.

답변을 다실때
자세한 설명도 좀 부탁드립니다.

그럼..
civilian [civilian]   2010-03-12 00:10 X
1, 3, 5, 2, 4

이유는?



찍었음. ㅋㅋ
Lyn [tohnokanna]   2010-03-12 01:42 X
위와 같은 문제일경우 2 > 1=3=4=5
Lyn [tohnokanna]   2010-03-12 01:49 X
현재 판매되는 32bit CPU는 실수연산과 정수연산의 속도가 같음... 단 2번에 한해서만 정수형을 실수형으로 변환하는 과정이 추가됨으로 느림.
장성호 [nasilso]   2010-03-12 01:58 X
오 그런가요?
그래도 double형 연산은 쬐금은 더 느리지 않을까요?
덧셈이라도 하더라도 4Byte짜리 끼리 덧셈보다는 8Byte 짜리 끼리 덧셈이 쬐금은 더 느릴것 같은데..

Lyn [tohnokanna]   2010-03-12 02:08 X
같은 8byte 끼리의 연산이라도, double은 CPU에서 한방에 연산하는 명령어를 제공하기때문에 속도는 같습니다.
우리가 실제 느끼는 속도는 CPU 내부의 micro operation 이 이뤄지는 명령어 수가 아니라 CPU가 제공하는 외부인터페이스의 명령어 수이기 때문에요... 실제 내부에선 얼마가 걸리더라도 외부에는 cpu의 시간단위인 "클럭" 단위 이하의 시간은 존재하지 않으니까요... 그쪽까진잘 모르지만, 아마 실제 계산량은 4byte 쪽이 적을지도 모르죠...

하지만 결국 우리에게 공개된 명령어에선 double 이나 int 연산이나 같은 클럭을 소모하는 명령어라는거죠.

예외적으로.. int64형 같은 경우 32bit에서 int64형 연산을 위한 명령어를 제공하지 않으므로, 32bit 2개로 분해해서 연산하는 과정을 거칩니다. 그래서 느리죠... 물론 64bit os라면 상관없겠지만.
Nibble [gameover]   2010-03-12 09:04 X
빠른순 1 > 3 > 4 > 5 >>> 2
큰 용량은 메모리에서 가져오는 속도가 다르죠. 당연하게도 블럭 단위로 캐싱 되거든요. 2는 casting 이 추가 되는 것 맞구요. 같은 int 끼리의 연산도 대개의 경우 생성시간을 제외하곤 지역 > 전역이 됩니다. 지역의 경우 확률적으로 캐싱될 가능성이 높으니까요.
Nibble [gameover]   2010-03-12 09:05 X
정수는 늘 빠릅니다. (GPU 제외)
신성기 [barmi]   2010-03-12 09:10 X
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로 바이너리가 만들어지는 지에 따라서도 미묘한 차이를 보입니다.

참고하시기 바랍니다.
Lyn [tohnokanna]   2010-03-12 09:21 X
하나의 연산이 1클럭으로 처리되는것은 물론 아니지만, 적어도 곱셈은 정수와 실수 둘다 같은 클럭을 소모합니다.
Lyn [tohnokanna]   2010-03-12 09:22 X
그리고 캐싱되는 블럭단위는 8바이트의 배수이므로 이 상황에서는 의미가 없습니다.
신성기 [barmi]   2010-03-12 10:22 X
곱셈에 있어 정수와 실수 모두 같은 클럭을 사용한다는 게 좀 이상합니다.
제 얘기는 MUL(IMUL)과 MULPD,MULPS,MULSD,MULSS관련 instruction이 모두 같은 CLK으로 실행되지 않는다는 의미입니다.
즉, MUL이 MULPD보다 적은 CLK으로 수행됩니다.
Nibble [gameover]   2010-03-12 11:33 X
Lyn님 직접 테스트 코드 작성해서 돌려보세요. 다릅니다. 저 다섯경우 모두가요.
Nibble [gameover]   2010-03-12 11:41 X
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등에서 표시한다.

이렇게 하시면 보다 정확한 결과를 얻을 수 있습니다.
Nibble [gameover]   2010-03-12 11:57 X
제 테스트 결과 (약간의 오차는 있음. rdtsc 수행클럭 포함 10회 연산의 클럭임)

1. 81
2. 1116
3. 162
4. 162
5. 252

1, 3 = 4, 5, 2 순인데, 3과 4는 많은 용량을 처리할때 속도차를 보일 수 밖에 없습니다.
Nibble [gameover]   2010-03-12 12:02 X
__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);
}
Nibble [gameover]   2010-03-12 12:30 X
신성기님이 92년도에 보신 책이시면 음.. MASM Bible쯤 되겠네요. 거긴 clock cycle이 잘 나와있었죠 : )
서울대 모 교수씨가 쓴 누렁이 책은 개판이었고...
요즘은 asin atan 같은 연산의 클럭은 잘 나와있는데 일반연산들의 클럭은 안나오더군요. CPU군이 많아지다보니...

+ -

관련 글 리스트
962 [퀴즈] 다음 계산중 어느게 속도가 빠를까요? 장성호 12292 2010/03/12
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.