针对gcc中的小型或固定大小数据的优化memcpy

时间:2010-11-14 22:52:21

标签: c++ gcc memcpy

我使用memcpy复制可变大小的数据和固定大小的数据。在某些情况下,我会复制少量内存(只有少量字节)。在海湾合作委员会中,我记得memcpy曾经是一个内在的/内置的。然后分析我的代码(使用valgrind)我在glibc中看到成千上万次调用实际的“memcpy”函数。

使用内置功能需要满足哪些条件?我可以快速推出自己的memcpy,但我确信内置版比我能做的更有效。

注意:在大多数情况下,要复制的数据量可用作编译时常量。

CXXFLAGS:-O3 -DNDEBUG

我正在使用的代码,强制内置,如果你取消_ 内置前缀,则不使用内置。这是使用T = sizeof(type)从各种其他模板/函数调用的。使用的大小是1,2,4的倍数,50-100字节的大小,以及一些更大的结构。

template<int T>
inline void load_binary_fixm(void *address)
{
    if( (at + T) > len )
        stream_error();

    __builtin_memcpy( address, data + at, T );
    at += T;
}

1 个答案:

答案 0 :(得分:2)

对于T很小的情况,我会专门使用原生作业。

例如,在T为1的情况下,只需指定一个字符。

如果您知道地址已对齐,请为您的平台使用适当大小的int类型。

如果地址未对齐,您可能最好进行适当数量的字符分配。

这一点是为了避免分支并保留一个计数器。

如果T很大,如果你做得比库memcpy()更好,我会感到惊讶,并且函数调用开销可能会在噪声中丢失。如果你想进行优化,请查看周围的memcpy()实现。有些变体使用扩展指令等。

更新

查看关于内联memcpy的实际(!)问题,编译器版本和平台等问题变得相关。出于好奇,您是否尝试过使用std :: copy,如下所示:

template<int T>
inline void load_binary_fixm(void *address)
{
    if( (at + T) > len )
        stream_error();

    std::copy(at, at + T, static_cast<char*>(address));
    at += T;
}