相关疑难解决方法(0)

如何提高memcpy的性能

摘要:

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)

c cvi memcpy visual-studio memory-bandwidth

48
推荐指数
4
解决办法
4万
查看次数

非常快速的图像处理memcpy?

我在C中进行图像处理,需要在内存周围复制大块数据 - 源和目标永远不会重叠.

使用GCC(其中SSE,SSE2但不是SSE3可用)在x86平台上执行此操作的绝对最快方法是什么?

我希望解决方案可以是汇编还是使用GCC内在函数?

我发现下面的链接,但不知道它是否去了解它的最佳方式(笔者也表示有一些错误):http://coding.derkeiler.com/Archive/Assembler/comp.lang.asm. 86/2006-02/msg00123.html

编辑:请注意,副本是必要的,我无法复制数据(我可以解释为什么,但我会饶你解释:))

c optimization assembly image-processing memcpy

32
推荐指数
4
解决办法
4万
查看次数

如何从非常大的列表中按索引有效地删除元素?

我有一个非常大的整数列表(大约 20 亿个元素)和一个带有索引(几千个元素)的列表,我需要从第一个列表中删除元素。我目前的方法是遍历第二个列表中的所有索引,将每个索引传递给RemoveAt()第一个列表的方法:

indices.Sort();
indices.Reverse();
for (i = 0; i < indices.Count; i++)
{
    largeList.RemoveAt(indices[i]);
}
Run Code Online (Sandbox Code Playgroud)

但是,大约需要 2 分钟才能完成。我真的需要更快地执行此操作。有没有办法优化这个?

我有一个带有 10 个内核的 Intel i9X CPU,所以也许是某种并行处理方式?

.net c# performance list generic-list

26
推荐指数
4
解决办法
1482
查看次数

使用SIMD指令重写memcpy/memcmp/...是有意义的

使用SIMD指令重写memcpy/memcmp/...在大型软件中是否有意义?

如果是这样,为什么gcc默认不为这些库函数生成simd指令.

此外,SIMD是否可以改进其他功能?

performance sse simd

12
推荐指数
2
解决办法
5694
查看次数

Array.Copy是否保持每个元素的原子读写保证?

C#确保某些类型始终具有原子读取和写入.在调用Array.Copy这两种类型的数组时,我是否有同样的保证?每个元素是否以原子方式读写?我浏览了一些源代码,但没有得到一个可靠的答案.

例如,如果我推出自己的代码来复制两个数组......

static void Copy<T>(T[] source, T[] destination, int length)
{
    for (int i = 0; i < length; ++i)
        destination[i] = source[i];
}
Run Code Online (Sandbox Code Playgroud)

...并且调用了Copy<int>变体,这保证了每个元素都是从原子上读取source并原子写入的,destination因为C#承诺int读取和写入都是原子的.我只是问是否Array.Copy保持这种保证(相反,使用它自己的专用内存块复制例程,可能会破坏这种保证).

.net c# atomic

5
推荐指数
1
解决办法
230
查看次数