3

我使用 memcpy 来复制可变大小的数据和固定大小的数据。在某些情况下,我会复制少量内存(只有少数字节)。在 GCC 中,我记得 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;
}
4

1 回答 1

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;
}
于 2010-11-15T00:06:10.180 回答