摘要:
memcpy似乎无法在真实或测试应用程序中在我的系统上传输超过2GB /秒.我该怎么做才能获得更快的内存到内存副本?
详细信息:
作为数据捕获应用程序的一部分(使用一些专用硬件),我需要将大约3 GB /秒的临时缓冲区复制到主内存中.为了获取数据,我为硬件驱动程序提供了一系列缓冲区(每个2MB).硬件将数据DMA数据到每个缓冲区,然后在每个缓冲区已满时通知我的程序.我的程序清空缓冲区(memcpy到另一个更大的RAM块),并将处理后的缓冲区重新发送到卡中再次填充.我遇到了memcpy足够快地移动数据的问题.似乎内存到内存的副本应该足够快,以便在我运行的硬件上支持3GB /秒.Lavalys EVEREST给了我一个9337MB /秒的内存复制基准测试结果,但即使在一个简单的测试程序中,我也无法通过memcpy获得接近这些速度的任何数据.
我通过在缓冲区处理代码中添加/删除memcpy调用来隔离性能问题.没有memcpy,我可以运行全数据速率 - 大约3GB /秒.启用memcpy后,我被限制在大约550Mb /秒(使用当前编译器).
为了在我的系统上对memcpy进行基准测试,我编写了一个单独的测试程序,它只是在某些数据块上调用memcpy.(我已经发布了下面的代码)我在我正在使用的编译器/ IDE(National Instruments CVI)以及Visual Studio 2010中都运行了这个.虽然我目前没有使用Visual Studio,但我愿意如果它将产生必要的性能,则进行切换.然而,在盲目地移动之前,我想确保它能解决我的memcpy性能问题.
Visual C++ 2010:1900 MB /秒
NI CVI 2009:550 MB /秒
虽然我并不感到惊讶,CVI比Visual Studio的显著慢,我很惊讶的是,memcpy的性能是这种低.虽然我不确定这是否可以直接比较,但这远低于EVEREST基准带宽.虽然我不需要那么高的性能水平,但至少需要3GB /秒.当然,标准库的实现不会比EVEREST使用的更糟糕!
在这种情况下,如果有的话,我可以做些什么来更快地使用memcpy?
硬件细节:AMD Magny Cours-4x八核128 GB DDR3 Windows Server 2003 Enterprise X64
测试程序:
#include <windows.h>
#include <stdio.h>
const size_t NUM_ELEMENTS = 2*1024 * 1024;
const size_t ITERATIONS = 10000;
int main (int argc, char *argv[])
{
LARGE_INTEGER start, stop, frequency;
QueryPerformanceFrequency(&frequency);
unsigned short * src = …Run Code Online (Sandbox Code Playgroud) 我收到这个错误.
error: warning: incompatible implicit declaration of built-in function ‘memcpy’ [enabled by default]
Run Code Online (Sandbox Code Playgroud)
这是代码:
int arr[ 12] = {1,0,0,0,0,0,0,0,0,0,9370, 0};
void *a = &arr;
memcpy(machine->mem, a,12*4);
Run Code Online (Sandbox Code Playgroud)
我做错了什么?
如果我想在另一个(在C中)复制一个结构,那么pro&con's是什么:
struct1 = struct2;
Run Code Online (Sandbox Code Playgroud)
VS
memcpy(&struct1, &struct2, sizeof(mystruct_t));
Run Code Online (Sandbox Code Playgroud)
它们是等价的吗?性能或内存使用有区别吗?
我正在做一些维护工作,遇到类似以下的事情:
std::string s;
s.resize( strLength );
// strLength is a size_t with the length of a C string in it.
memcpy( &s[0], str, strLength );
Run Code Online (Sandbox Code Playgroud)
我知道使用&s [0]如果它是std :: vector会是安全的,但是这是std :: string的安全使用吗?
我有一个正在执行memcpy的功能,但它占用了大量的周期.有没有比使用memcpy移动内存更快的替代/方法?
在C和C++中,当要复制的字节数为零时,memcpy进入变量是否是未定义的行为?const
int x = 0;
const int foo = 0;
memcpy( (void *)&foo, &x, 0 );
Run Code Online (Sandbox Code Playgroud)
这个问题并不纯粹是理论上的。我有一个场景,其中memcpy被调用,如果目标指针指向const内存,则大小参数保证为零。所以我想知道是否需要将其作为特殊情况处理。
我希望从特定的起点将特定长度的内容从一个缓冲区复制到另一个缓冲区.我检查过memcpy()但只需要复制内容的长度,而我也要指定起始索引.
是否有任何功能可以做到这一点,还是有任何好的方法来完成现有的memcpy功能?
我正在将一个项目移植到iPhone上,它使用的realloc并且memcpy没有找到.要包含的标题是什么?
这是一个混合Objective C和C++的项目,我开始迷失方向.
在此先感谢您的帮助!
是底层位表示一个std::array<T,N> v和T u[N]一样的吗?
换句话说,将N*sizeof(T)字节从一个复制到另一个是否安全?(通过reinterpret_cast或memcpy.)
编辑:
为了澄清,重点是相同的位表示和reinterpret_cast.
例如,假设我将这两个类放在一些简单的可复制类型上T,对于某些类N:
struct VecNew {
std::array<T,N> v;
};
struct VecOld {
T v[N];
};
Run Code Online (Sandbox Code Playgroud)
还有遗留功能
T foo(const VecOld& x);
Run Code Online (Sandbox Code Playgroud)
如果表示相同,则此调用是安全的并且避免复制:
VecNew x;
foo(reinterpret_cast<const VecOld&>(x));
Run Code Online (Sandbox Code Playgroud) 我在C中进行图像处理,需要在内存周围复制大块数据 - 源和目标永远不会重叠.
使用GCC(其中SSE,SSE2但不是SSE3可用)在x86平台上执行此操作的绝对最快方法是什么?
我希望解决方案可以是汇编还是使用GCC内在函数?
我发现下面的链接,但不知道它是否去了解它的最佳方式(笔者也表示有一些错误):http://coding.derkeiler.com/Archive/Assembler/comp.lang.asm. 86/2006-02/msg00123.html
编辑:请注意,副本是必要的,我无法复制数据(我可以解释为什么,但我会饶你解释:))
memcpy ×10
c ×6
c++ ×5
assembly ×1
c++03 ×1
c++11 ×1
constants ×1
cvi ×1
header ×1
objective-c ×1
optimization ×1
performance ×1
realloc ×1
stdstring ×1
struct ×1