3

システムで memcpy のパフォーマンスが memmove より遅いのはなぜですか?

thisthisなどの他の SO の質問を読むと、memcpy は memmove よりも高速に動作するはずであり、直感的にはそうであるはずです。結局のところ、memcpy が行うチェックは少なく、man ページも彼らの言うことと一致します。

ただし、各関数内で費やされた時間を測定すると、memmove が memcpy を上回っています。さらに、memset が memcpy や memmove ができない最適化の恩恵を受ける可能性があると思われる場合、memset にも勝っているようです。なぜそうなるのでしょうか?

コンピューターでの結果 (多数のうちの 1 つ):

[INFO] (ex23.c:151 func: main) Normal copy: 109092
[INFO] (ex23.c:198 func: main) memcpy: 66070
[INFO] (ex23.c:209 func: main) memmove: 53149
[INFO] (ex23.c:219 func: main) memset: 52451

この結果を得るために使用されるコード:

#include <stdio.h>
#include <string.h>
#include "dbg.h" // debugging macros
#include <time.h>

int main(int argc, char *argv[])
{
    char from[10000] = {'a'};
    char to[10000] = {'c'};
    int rc = 0;
    struct timespec before; 
    memset(from, 'x', 10000);
    memset(to, 'y', 10000);

    clock_gettime(CLOCK_REALTIME, &before);

    // naive assignment using a for loop
    normal_copy(from, to, 10000);
    struct timespec after;
    clock_gettime(CLOCK_REALTIME, &after);
    log_info("Normal copy: %ld", (after.tv_nsec - before.tv_nsec));


    memset(to, 'y', 10000);
    clock_gettime(CLOCK_REALTIME, &before); 
    memcpy(to, from, 10000);
    clock_gettime(CLOCK_REALTIME, &after);
    log_info("memcpy: %ld", (after.tv_nsec - before.tv_nsec));

    memset(to, 'y', 10000);
    clock_gettime(CLOCK_REALTIME, &before);
    memmove(to, from, 10000);
    clock_gettime(CLOCK_REALTIME, &after);
    log_info("memmove: %ld", (after.tv_nsec - before.tv_nsec));

    memset(to, 'y', 10000);
    clock_gettime(CLOCK_REALTIME, &before);
    memset(to, 'x', 10000);
    clock_gettime(CLOCK_REALTIME, &after);
    log_info("memset: %ld", (after.tv_nsec - before.tv_nsec));

    return 0;
}
4

1 に答える 1

1

@Carl Norum と @Greg Hewgill が言うように: 効果をキャッシュします。

あなたは確かにキャッシュされたメモリの影響を経験しています。テストを並べ替えて、結果を比較します。memcpy() 前後でテストしたところmemmove()、2回目memcpy()は同じようmemove()に動作し、1回目よりも高速でしたmemcpy()

于 2013-08-11T22:40:10.750 に答える