先来看看微软开发工具下的 memcpy() 源代码(E:\Microsoft Visual Studio 9.0\VC\crt\src):

/***
*memcpy.c - contains memcpy routine
*
*       Copyright (c) Microsoft Corporation. All rights reserved.
*
*Purpose:
*       memcpy() copies a source memory buffer to a destination buffer.
*       Overlapping buffers are not treated specially, so propogation may occur.
*
*******************************************************************************/

#include <cruntime.h>
#include <string.h>

#ifdef _MSC_VER
#pragma function(memcpy)
#endif  /* _MSC_VER */

/***
*memcpy - Copy source buffer to destination buffer
*
*Purpose:
*       memcpy() copies a source memory buffer to a destination memory buffer.
*       This routine does NOT recognize overlapping buffers, and thus can lead
*       to propogation.
*
*       For cases where propogation must be avoided, memmove() must be used.
*
*Entry:
*       void *dst = pointer to destination buffer
*       const void *src = pointer to source buffer
*       size_t count = number of bytes to copy
*
*Exit:
*       Returns a pointer to the destination buffer
*
*Exceptions:
*******************************************************************************/

void * __cdecl memcpy (
        void * dst,
        const void * src,
        size_t count
        )
{
        void * ret = dst;

#if defined (_M_IA64)

        {


        __declspec(dllimport)


        void RtlCopyMemory( void *, const void *, size_t count );

        RtlCopyMemory( dst, src, count );

        }

#else  /* defined (_M_IA64) */
        /*
         * copy from lower addresses to higher addresses
         */
        while (count--) {
                *(char *)dst = *(char *)src;
                dst = (char *)dst + 1;
                src = (char *)src + 1;
        }
#endif  /* defined (_M_IA64) */

        return(ret);
}


在 16/32 位系统中, 一次拷贝一个字节的情况是非常浪费 CPU 效率的. 因为他们一般都要半字或字对齐. 读写数据一次就是 16/32bit. 如果在奇数地址上访问一个字节效率可想而知. 所以, 对于像 ARM 这种 4Byte 对齐的CPU而言下面的这种写法是效率最高的, 而且效率相比于一次一字节的情况, 不止是 4 倍的效率增长:

void my_memcpy(void * dest, const void * src, unsigned int n)
{
    unsigned int i = 0;
    long * Dest = (long *)dest;
    long * Src  = (long *)src;

    for (i = 0; i < (n >> 2); i++) {
        Dest[i] = Src[i];
    }
}

当然了, 如果不能保证使用的 CPU 平台是 4B 对齐的, 可以在上述程序中添加代码来尽量保证实现高效率.

void my_memcpy(void * dest, const void * src, unsigned int n)
{
    unsigned int i = 0;
    long * Dest = (long *)dest;
    long * Src  = (long *)src;

    if (((unsigned long)Src) % 4 == 0) && ((unsigned long)Dest % 4 == 0) {
        for (i = 0; i < (n >> 2); i++) {
            Dest[i] = Src[i];
        }
    } else {
        memcpy(dest, src, n);
    }
}
而这种调整只有在对性能要求敏感的场合使用, 如果不是这样还是要使用标准的库函数. 毕竟可移植性和可维护性也是很重要的.

===============================================================================================================================





Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐