我正在尝试创建一个像memcpy()一样的函数InvertCopy(),除了它在执行复制时也会反转每个位。 首先我做了这个:
void InvertCopy( void *v_dst, const void *v_src, int length )
{
char *dst = v_dst;
const char *src = v_src;
for ( ; length>0; length-- )
{
*(dst++) = ~ *(src++);
}
}
它有效,但出于性能考虑,我想利用处理器的字大小。对于那个整数指针会很好,除了我的InvertCopy应该处理int指针和非int指针,因此我不能简单地将指针转换为int * - 在某些处理器上它实际上可能导致硬件故障。
为了更容易,我决定在处理未对齐的缓冲区时允许更慢的性能,并且只在可能的情况下进行此优化。结果如下:
#define IS_ALIGNED( addr, size ) ( ((uintptr_t)(addr)) % (size) == 0 )
void InvertCopy( void *v_dst, const void *v_src, int length )
{
char *dst = v_dst;
const char *src = v_src;
/* Optimization starts here! */
if ( IS_ALIGNED( dst, sizeof(int) ) && IS_ALIGNED( src, sizeof(int) ) )
{
int *i_dst = v_dst;
const int *i_src = v_src;
for ( ; length >= sizeof(int); length -= sizeof(int) )
{
*(i_dst++) = ~ *(i_src++);
}
dst = (char*) i_dst;
src = (const char*) i_src;
}
/* Optimization done. */
for ( ; length>0; length-- )
{
*(dst++) = ~ *(src++);
}
}
这很棒,实际上我的实验工作得非常快。
但这是对的吗? 在使用-Wcast-align进行编译时,GCC没有给我任何警告,但我认为这并不意味着什么,因为当我在没有先检查对齐的情况下执行相同操作时它也没有说什么。
我做得对,还是应该担心对齐问题?
答案 0 :(得分:0)
对我来说很好看。只需使用各种路线的源和目标缓冲区编写一些单元测试。
另一项改进是尝试先执行单字节复制 ,以使缓冲区达到所需的对齐。当然,这仅在两个缓冲区都以相同的对齐偏移量开始时才有效。
还有一些关于优化memcpy
的好文章(当然也适用于你的任务)。