pos >> = 1 과 pos = pos / 2.0 이 속도차이가 많이 나는 이유는....?
글쓴이: jungjury / 작성시간: 금, 2005/12/23 - 11:56오전
#include <stdio.h> int main() { long int in1,in2,num1, num2, i, maxlength, length,temp; long unsigned int pos; while ( scanf("%d %d",&in1, &in2) == 2 ){ if ( in1 > 0 && in2 > 0 && in1 <=1000000 && in2<=1000000 ) { num1 = in1; num2 = in2; if ( num1 > num2 ){ temp = num1; num1 = num2; num2 = temp; } maxlength = 0; for ( i = num1; i<=num2; i++) { length = 1; pos =i; while ( pos !=1 ) { while ( (pos % 2) == 0 ) { pos>>=1; // <---------------------------------------- length=length+1; } if ( pos != 1 ) { pos = pos * 3 + 1; length=length+1; } } if ( maxlength < length ) maxlength = length; } printf("%ld %ld %ld\n",in1, in2, maxlength); } } return 0; }
http://www.programming-challenges.com/ 에서...
Problem: The 3n+1 problem (110101)를 풀었는데..
위 소스코드에서..
pos = pos / 2.0;으로 하면 10초가 걸려 시간 초과되고....
pos >> = 1; 으로 바꾸면 3.909초가 걸려 통과됩니다...
왜 이렇게 차이가 많이 나는지 궁금합니다..
Forums:
나누기 연산이 비싸기 때문입니다. 연산에 들어가는 CPU Cycl
나누기 연산이 비싸기 때문입니다.
연산에 들어가는 CPU Cycle 같은 자료를 찾아 보시면 잘 나옵니다.
정수 나누기 연산은 연산 중 가장 비싼 연산이고, 쉬프트 연산은 아주 싼 연산입니다.
/2.0 은 실수 연산이고>>1 은 정수 연산이기 때문
/2.0 은 실수 연산이고
>>1 은 정수 연산이기 때문입니다...
제대로된 컴파일러이면 /2 나 >>1 은 내부에서 똑같이 처리하기 때문에
속도차이가 나지 않을 껍니다.
말씀하신데로... pos=pos / 2 로 해보니.. 3.
말씀하신데로...
pos=pos / 2 로 해보니..
3.284초로.. Solved 결과가 나옵니다....
정수 연산과 실수 연산도 속도 차이가 나는군요... :roll:
안녕하세요 : )
[quote="jungjury"]정수 연산과 실수 연산도 속도 차이가 나
어마어마한 차이가 나지요. 예전에 386쓰다가 486으로 바꿨을 때 수치계산 프로그램을 돌려보고 감격했던 기억이 ㅠ.ㅠ
int pos;pos = pos / 2.0이 연산은 불필요
int pos;
pos = pos / 2.0
이 연산은 불필요한 오버헤드가 많은 코드 입니다.
일단 pos 가 int 이므로 pos = pos/2.0 에서 pos/2.0 에서 오른쪽 피연산자가 부동소수이므로 왼쪽 pos가 부동소수로 변환이 됩니다.
부동소수 -> 정수, 정수 -> 부동소수 변환은 꽤 복잡해서 오버헤드가 생각보다 큰편입니다.
그런 다음 부동소수/부동소수 형식으로 나눗셈이 진행되는데 정수 나눗셈보다 훨씬 오버헤드가 큽니다.
(보통 부동소수/부동소수 는 부동소수를 부동소수로 직접 나누는 것 보다, 오른쪽 피연산자의 역수를 구해서 부동소수 * 역수 형식으로 변경해서 곱셈을 하는게 더 효율적이여서 대부분 내부적으로 그렇게 처리합니다. 부동소수의 역수를 구하는 것도 큰 일이고, 부동소수 곱셈도 큰 일이지요.)
연산 결과가 부동소수인데 pos = pos/2.0 에서 = 의 왼쪽 pos가 int 이므로 연산 결과인 부동소수 가 다시 int 로 변환이 됩니다. 이때 또 오버헤드가 발생합니다.
금융권에서 일하려고 한다면, 부동소수가 어떻게 구현이 되었는지 꼭 알아두셔야 합니다.
부동소수 사칙 연산이 어떻게 구현됐는지는 모르더라도 IEEE754 를 따른 부동소수 표기법과 그에 따른 한계에 대해서는 꼭 숙지를 해야 하지요.
댓글 달기