이전 포스팅에서 memcpy() 함수와 for 문을 이용한 메모리 복사의 속도 실험을 해 본적이 있었는데요.

  

2012/07/16 - [컴퓨터일반] - C/C++ memcpy() 함수 속도

 

오늘은 그 연장선으로 memmove() 함수의 속도 실험을 수행해 봤습니다.

 

memcpy() 함수는 인자로 들어가는 두 메모리가 다른 주소여야 하지만

 

다음과 같은 정의의 memmove() 함수는 source 와 destination 이 같은 주소여도 상관이 없는 것으로 알고 있습니다.

 

void * memmove ( void * destination, const void * source, size_t num );

 

즉 memmove() 함수는 소스가 겹쳐지는 부분에 대해 내부적으로 고려를 해주는 뭔가가 더 들어간다는 거죠.

 

디지털 필터를 설계 할 때 memory shift 구현에 memmove() 를 사용하는 것이 좋을 것 같다는 생각이 들더군요.

 

그래서 다음과 같이 속도 실험을 해 봤습니다.

 

for 문을 사용할 때, 배열의 높은 인덱스에서 낮은 인덱스로 복사 할 때, 배열의 낮은 인덱스에서 높은 인덱스로 복사 할 때, 이렇게 세가지 경우에 대해 비교해 봤는데, 생각보다 속도가 빠르진 않더군요.

 

실험 코드는 다음과 같이 작성했습니다.

 

#include <iostream>

#include <stdio.h>

#include <string.h>

#include <time.h>

#include <fstream>

#include <math.h>

 

using namespace std;

 

int main()

{

    time_t start,end;

    double dif, average_time,average_time1, average_time2, sum_time;

    unsigned k, i;

    unsigned N_sim, N_buffer;

 

    ofstream fout("abc.txt");

    N_sim=1000000;

 

    int * test1;

   

    int N;

    for (N=10;N<17;N++)

    {

        N_buffer=(unsigned)pow(2,N);

 

        test1 = new int[N_buffer];

 

 

        // use for loop

        sum_time=0;

        for (k=0;k<N_sim;k++)

        {

            time(&start); // start time

            for (i=1;i<N_buffer;i++)

            {

                test1[i-1]=test1[i];

            }

            time(&end);

            dif = difftime(end,start);

            sum_time+=dif;

        }

        average_time=sum_time/(double)N_sim;

   

        // use memmove, Low to High

        sum_time=0;

        for (k=0;k<N_sim;k++)

        {

            time(&start); // start time

            memmove(test1+1, test1,(N_buffer-1)* sizeof(int));

            time(&end);

            dif = difftime(end,start);

            sum_time+=dif;

        }

        average_time2=sum_time/(double)N_sim;

           

        // use memmove, High to Low

        sum_time=0;

        for (k=0;k<N_sim;k++)

        {

            time(&start); // start time

            memmove(test1, test1+1,(N_buffer-1)* sizeof(int));

            time(&end);

            dif = difftime(end,start);

            sum_time+=dif;

        }

        average_time1=sum_time/(double)N_sim;

   

        fout << N_buffer << "\t" << average_time << "\t" << average_time1 << "\t" << average_time2 << endl;

        cout << N_buffer << "\t" << average_time << "\t" << average_time1 << "\t" << average_time2 << endl;

   

        delete []test1;

    }

 

    fout.close();

      return 0;

}

 

결과는 이렇게 나오더군요.


memmove  속도 실험

 

실험 결과에서 배열의 높은 인덱스에서 낮은 인덱스로 복사 할 때의 경우에는 for 문을 사용할 때보다 오히려 속도가 느리더군요.

 

배열의 낮은 인덱스에서 높은 인덱스로 복사 할 때는 아주 약간 빠르긴 한데 그리 체감 할 정도는 아닌 것 같습니다.

 

지난 실험에서 memcpy() 함수가 for 문을 사용할 때에 비해 약 5 배 정도 빨랐던 것 같은데 C/C++ 로 memory shift 를 구성할 때 메모리를 하나 더 둬서 memcpy() 함수를 사용하는 것이 속도 면에서는 더 좋을 수 도 있겠다는 생각이 드는군요.

 

의견 있으신 분들은 댓글 남겨 주세요.


  1. imagej 2013.03.12 10:06

    memmove는 사실 잘 사용하지 않는 구문이라 속도를 비교할 기회가 없었는데 포스팅을 보고 예상외 결과네요.

    실제 memcpy 는 for나 while 같은 루프에 비해서 순간적으로 이루어 져서 memmove 역시 빠를거라 생각했는데....

    근데 만일 같은 메모리에서 인덱스를 밀거나 당겨서 이동하는거 보다 서로 다른 메모리에(리스크가 있겠지만...) 무브를 하게되면 내부적으로 복사를 또 할 필요가 없기때문에 더 속도가 나지 않을까 생각이 드네요.

    • 남성 2013.03.12 12:57 신고

      방문해 주셔서 감사합니다. ^^
      저도 memmove 는 잘 사용하지 않긴 했지만 그래도 생각보다 느려서 당황스럽더군요. 아~~ 이래서 memmove 는 잘 안쓰나 싶기도 하고요. memory shift 는 아래 주소에 설명했던 C++ STL 의 deque 가 가장 빠르더군요.
      http://iamaman.tistory.com/631

  2. ㅇㅇ 2020.03.23 18:49

    버퍼가 중첩되는 부분 때문일 것 같아서
    다른 버퍼를 사용하신 memcpy테스트 코드를 memmove로 바꾸니 성능이 같아지네요..

    왜 내부적으로 버퍼가 중첩된 부분에 저런 처리가 들어가는지 모르겠지만 찾아보니 그냥 이런 글이 있네요.
    http://ehpub.co.kr/memmove-%ED%95%A8%EC%88%98/

    +참고로 이 페이지의 memmove 테스트 코드를 memcpy로 강제로 해버려도 제 환경에서는 memmove랑 속도가 같네요.

+ Recent posts