【问题标题】:Casting general-pointer to int-pointer for optimization将通用指针转换为 int 指针以进行优化
【发布时间】:2014-06-20 07:28:45
【问题描述】:

我正在尝试创建一个功能类似于 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++);
    }
}

这很棒,而且在我的实验中实际上运行得更快。

但这是正确的吗? GCC 在使用 -Wcast-align 进行编译时没有给我任何警告,但我认为这并不意味着什么,因为当我在没有先检查对齐情况的情况下执行相同操作时,它也什么也没说。

那么我做得对还是应该担心对齐问题?

【问题讨论】:

  • 我觉得没问题。但更好的方法是复制前几个字节,直到两个缓冲区对齐。这样,您将更频繁地使用优化。请参阅此相关问题:stackoverflow.com/questions/1898153/…

标签: c pointers casting alignment warnings


【解决方案1】:

我觉得不错。只需使用各种对齐方式的源和目标缓冲区编写一些单元测试。

另一个改进是尝试进行单字节复制first,以使缓冲区达到所需的对齐。当然,这只有在两个缓冲区都以相同的对齐偏移量开始时才有效。

还有一些关于优化memcpy 的好文章(当然也适用于您的任务)。

【讨论】:

  • 感谢您的改进,但正如您所提到的,这仅适用于缓冲区具有相同对齐偏移量的情况,而不适用于一般情况。关于单元测试——我确实检查了代码,但我担心如果我尝试在一些奇怪的微控制器上运行代码会发生什么。从您的第一个链接上的示例中,我看到它们的效果完全相同,所以我想这很好。
猜你喜欢
  • 2017-02-12
  • 1970-01-01
  • 2012-03-02
  • 2014-05-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-18
  • 2021-01-16
相关资源
最近更新 更多