速度权衡:经常从文件读取与使用动态内存存储它

时间:2011-03-30 18:08:58

标签: c image cuda file-handling

我正在编写一个C程序,它涉及读取图像文件并只读取一次图像的每个像素。那么我应该使用fread()读取一次文件并将其存储在一些动态变量(堆变量)中,或者频繁使用每个像素的fread()? 图像尺寸为1000 * 1000至5000 * 5000。  我将在MPI和CUDA中扩展相同的程序。我将不胜感激任何其他建议。 谢谢。

8 个答案:

答案 0 :(得分:4)

即使是12位彩色ARGB图像,对于5,000 * 5,000像素分辨率也需要大约150 MB,这完全在所有当前PC甚至许多GPU卡的功能范围内。如果你有那种可用的内存,你应该在动态分配的数组中读取一次,或者沿着那些行读取它。它允许您在大I / O块中读取整个图像,速度更快,并使用直接内存操作(img[1234][4321][RED] = 34),而不是使用I / O函数使代码复杂化。

如果您没有可用的内存,请查看mmap()或您的操作系统存在的任何内存,以将文件映射到虚拟内存。你仍然可以使用直接内存操作,而不必将整个内容加载到内存中,尽管它在计算上会更昂贵。

也就是说,现代操作系统执行广泛的缓存和数据预取,因此使用fread()可能不会慢得多。此外,在目前使用glibc-2.3或更高版本的Linux系统上,即使应用程序使用标准mmap()函数执行I / O,也可以使用stdio进行文件访问。

答案 1 :(得分:1)

这取决于。您应该尝试估计将运行您的软件的大多数计算机上的内存量。它还取决于你的代码的速度如何。

显然,一种方法更快,而另一种方法使用更多内存。一般来说,你可能可以将它加载到大多数现代计算机的内存中,这更容易。但是你必须在你的特定情况下权衡利弊。

答案 2 :(得分:1)

一般来说,我发现处理文件的最快方法是尝试在一个大的I / O中读取整个内存,然后从内存中处理内存。它通常使代码更简单太。

您当然必须担心可能不适合任何可用连续内存块的文件。如果你正确处理(而不仅仅是保释),代码就会变得复杂得多。作为一名经过认证的懒惰程序员,如果我能逃脱它,我宁愿保释。 : - )

答案 3 :(得分:1)

这是另一个可以帮助您做出决定的问题:How exactly does fopen(), fclose() work?

如果您正在寻找速度,最好将整个文件一次加载到内存中并在那里进行操作。这样你就可以避免对硬盘驱动程序的无意调用来提供数据。当你开始谈论为5k图像提供25,000,000个不同的4字节块(假设32位RGBA)时,你可能会寻找潜在的大量搜索,阅读和等待。

这是经典的内存与速度权衡之一。如果您的客户有足够的内存,那么最好将所有数据加载到内存中然后执行转换。

否则尝试一次加载足够的数据(分页),使其快速并适合您所针对的内存配置文件。

答案 4 :(得分:1)

取决于您需要处理哪种算法。 5000 * 5000的图像大约为95 Mb。没什么大不了的。

在Gpu端,您可以以大约4MB-16MB的块大小异步上传到GPU内存以使带宽饱和

#pseudocode:

 for chunk in fread(4096MB):
     gpu.uploadAsync (chunk) # will not block
 gpu.execute() #wait that all the previous memory transfers are completed.

你必须在cuda上使用固定内存,我认为如果你的内存映射文件复制块 会更快。

像往常一样描述您的应用程序以获得最佳调整。

答案 5 :(得分:0)

在windows下使用mmap()linux或mapviewoffile()。

答案 6 :(得分:0)

将其存储在内存中肯定会更快。如果您每次都从硬盘驱动器中读取小块,则由于访问时间最短等原因,您总是会遇到延迟。

答案 7 :(得分:0)

我打算把它写成评论,但它变得太长了。但至关重要......

我同意T.E.D.和乔纳森伍德:

  

一般来说,我发现了最快捷的方式   处理文件是尝试阅读   整个事情在一个大的记忆中   I / O,并处理内存不足   从那时起。它经常使   代码也更简单。

-T.E.D

  

这取决于。你应该试试   估计大多数内存量   将运行您的软件的计算机。   它还取决于速度如何关键   你的代码是。

     

显然,一种方法更快   而另一个使用更多的内存。   一般来说,你可能没问题   将它装入大多数现代的内存中   电脑,这更容易。但是你   必须权衡利弊   你的具体情况

-Jonathan Wood

请记住,具有32位颜色的5000 * 5000像素占用大约100兆字节的内存(+可能是一些开销,无论您的软件需要什么)。我会说(最好的猜测斯泰森 - 哈里森价值)大多数现代台式电脑至少有1或2千兆字节的内存(我的是2008年买的,有4个),所以即使整个东西都加载也没那么多笔记本电脑可能会有更少的内存。

CUDA方面也很有意思(我对CUDA几乎一无所知),数据加载到GPU的内存中吗?支持CUDA的GPU通常有多少内存? PCI-e总线会成为瓶颈(可能不是......?)?了解具有CUDA支持的常见CUDA-enabled台式机和笔记本电脑GPU的内存容量。

一种妥协可能是试图缓冲读取,让另一个线程“预读”文件中的数据,而其他(s)进程(以及它们去的空闲内存)数据。