pos >> = 1 과 pos = pos / 2.0 이 속도차이가 많이 나는 이유는....?

jungjury의 이미지

#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초가 걸려 통과됩니다...

왜 이렇게 차이가 많이 나는지 궁금합니다..

kimsk99의 이미지

나누기 연산이 비싸기 때문입니다.

연산에 들어가는 CPU Cycle 같은 자료를 찾아 보시면 잘 나옵니다.

정수 나누기 연산은 연산 중 가장 비싼 연산이고, 쉬프트 연산은 아주 싼 연산입니다.

hyperhidrosis의 이미지

/2.0 은 실수 연산이고

>>1 은 정수 연산이기 때문입니다...

제대로된 컴파일러이면 /2 나 >>1 은 내부에서 똑같이 처리하기 때문에
속도차이가 나지 않을 껍니다.

jungjury의 이미지

말씀하신데로...

pos=pos / 2 로 해보니..

3.284초로.. Solved 결과가 나옵니다....

정수 연산과 실수 연산도 속도 차이가 나는군요... :roll:

안녕하세요 : )

kewlbear의 이미지

jungjury wrote:
정수 연산과 실수 연산도 속도 차이가 나는군요... :roll:

어마어마한 차이가 나지요. 예전에 386쓰다가 486으로 바꿨을 때 수치계산 프로그램을 돌려보고 감격했던 기억이 ㅠ.ㅠ
ssehoony의 이미지

int pos;

pos = pos / 2.0

이 연산은 불필요한 오버헤드가 많은 코드 입니다.

일단 pos 가 int 이므로 pos = pos/2.0 에서 pos/2.0 에서 오른쪽 피연산자가 부동소수이므로 왼쪽 pos가 부동소수로 변환이 됩니다.

부동소수 -> 정수, 정수 -> 부동소수 변환은 꽤 복잡해서 오버헤드가 생각보다 큰편입니다.

그런 다음 부동소수/부동소수 형식으로 나눗셈이 진행되는데 정수 나눗셈보다 훨씬 오버헤드가 큽니다.
(보통 부동소수/부동소수 는 부동소수를 부동소수로 직접 나누는 것 보다, 오른쪽 피연산자의 역수를 구해서 부동소수 * 역수 형식으로 변경해서 곱셈을 하는게 더 효율적이여서 대부분 내부적으로 그렇게 처리합니다. 부동소수의 역수를 구하는 것도 큰 일이고, 부동소수 곱셈도 큰 일이지요.)

연산 결과가 부동소수인데 pos = pos/2.0 에서 = 의 왼쪽 pos가 int 이므로 연산 결과인 부동소수 가 다시 int 로 변환이 됩니다. 이때 또 오버헤드가 발생합니다.

금융권에서 일하려고 한다면, 부동소수가 어떻게 구현이 되었는지 꼭 알아두셔야 합니다.
부동소수 사칙 연산이 어떻게 구현됐는지는 모르더라도 IEEE754 를 따른 부동소수 표기법과 그에 따른 한계에 대해서는 꼭 숙지를 해야 하지요.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.