3

I am writing a C program which involves reading a image file and reading each pixel of image just once. So should i read file once using fread() and store it in some dynamic variable(heap variable) or frequeently use fread() for each pixel?? Image will be of size 1000*1000 to 5000*5000. I will be extending the same program in MPI and CUDA. I would appreciate any other suggestions. Thank you.

4

8 回答 8

4

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

如果您没有那种可用的内存,请查看mmap()您的操作系统或任何等效的东西,以将文件映射到虚拟内存。您仍然具有使用直接内存操作的优势,而不必将整个内容加载到内存中,尽管计算成本会更高。

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

于 2011-03-30T18:24:56.573 回答
1

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

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

于 2011-03-30T18:14:43.877 回答
1

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

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

于 2011-03-30T18:20:25.287 回答
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 上使用固定内存,我认为如果您使用内存映射文件复制块会更快。

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

于 2011-03-30T20:56:02.543 回答
1

这里还有一个问题可以帮助你做出决定:fopen()、fclose() 究竟是如何工作的?

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

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

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

于 2011-03-30T18:24:54.543 回答
0

看看在windows下使用mmap() linux或者mapviewofile()。

于 2011-03-30T18:13:43.463 回答
0

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

于 2011-03-30T18:14:44.617 回答
0

我本来打算把它写下来作为评论,但它变得太长了。但切入正题...

我同意 TED 和乔纳森伍德的观点:

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

-TED

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

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

——乔纳森·伍德

请记住,具有 32 位颜色的 5000*5000 像素占用大约 100 兆字节的内存(+ 可能会有一些开销,以及您的软件需要的任何其他内容)。我会说(最好的猜测 Stetson-Harrison 值)大多数现代台式电脑至少有 1 或 2 GB 内存(我的内存是 2008 年购买的,有 4 个),所以即使整个东西都加载了,也不是很多同时,笔记本电脑的内存可能会更少。

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

一种妥协可能是尝试缓冲读数,让另一个线程“预读”文件中的数据,而其他线程则处理(并在执行过程中释放内存)数据。

于 2011-03-30T18:41:16.170 回答