【发布时间】:2016-05-16 01:52:10
【问题描述】:
我想编写一个逐字复制而不是逐字节复制的 memcpy 代码以提高速度。 (虽然我需要为最后一个或几个字节做一些逐字节的复制)。所以我希望我的源地址和目标地址正确对齐。 我在glibc中看到了memcpy的实现 https://fossies.org/dox/glibc-2.22/string_2memcpy_8c_source.html 它仅对目标地址进行对齐。但是即使源地址没有正确对齐,它也会导致总线错误(考虑在我的 cpu 中启用了对齐检查)我不确定如何使源地址和目标地址正确对齐。因为如果我尝试通过逐字节复制几个字节来对齐源,它也会改变目标地址,所以起初正确对齐的目标地址现在可能无法正确对齐。 那么有什么办法可以同时对齐吗?请帮帮我。
void memcpy(void *dst, void *src,int size)
{
if(size >= 8)
{
while(size/8) /* code will give sigbus error if src = 0x10003 and dst = 0x100000 */
{
*((double*)dst)++ = *((double*)src)++;
size = size - 8;
}
}
while(size--)
{
*((char*)dst)++ = *((char*)src)++;
}
}
【问题讨论】:
-
我不明白你如何对齐源地址和目标?对不起,我就是不明白?
-
@MartinJames 考虑我正在传递 src = 0x10003 dest = 0x100000 和 15 的大小。如果在 memcpy 中我想逐字复制,我想将 src 对齐为 8 的倍数(64位操作系统)所以下一个数字是 8 的倍数是 0x10006,所以对于前 3 个字节,我将逐字节复制,如果我这样做,src 将是 0x10006 但 dest = 0x100003,现在 dest 不是 8 的倍数. 这个问题还会继续。那么如何在这里对齐 src 和 dest 。如果不可能,还有其他方法可以逐字复制吗?
-
你不能。假设您正在移动一个单词块,如果源是奇数但目标是偶数,那么您在某种意义上是对齐未对齐的单词。另一方面,如果源是偶数而目标是奇数,则说明对齐的单词未对齐。您将读取或写入未对齐的单词 - 除了一次复制一个字节之外,别无他法。
-
@500-InternalServerError 所以如果我将 src 传递为奇数。根据这个fossies.org/dox/glibc-2.22/string_2memcpy_8c_source.html dest 检查内存对齐而不是源。所以代码总是会给出总线错误?
-
源地址和目标地址必须错位相同的数量(可以为0) 该函数将有一些前导来确定错位是否相同,复制0或更多未对齐的字节,使用较大的移动指令复制移动的主体,然后是处理复制任何最终字节的拖车。在代码中的所有点,必须检查是否有更多要复制的内容。当源和目标不是相同的错位时,这种算法几乎无法获得。