在C++中使用 fread 时实现固定大小缓冲区的最佳方法是什么?



假设您有一个整数文件,并且希望逐个读取它们。

您有两个缓冲选项。

  1. 声明大小为N的数组buffer,并使用setvbuf告诉fread要使用哪个缓冲区。然后,当调用函数fread读取整数时,您编写fread(&myInt, sizeof(myInt), 1, inputFile);

  2. 声明相同的数组buffer,但这次不使用函数setvbuf。相反,你自己去做缓冲工作。所以呼叫fread(buffer, bufferSize*sizeof(int), 1, inputFile)

据我所知,setvbuf的存在是为了让你的生活更轻松,但它是有代价的吗?就性能而言,您会使用哪种方法?

我不会使用您的两个示例。我不认为I/O的这一部分是性能瓶颈。

vbuf是输入例程在将数据放入目的地之前放置数据的区域。它可以用作缓存或预格式化缓冲区。

大多数情况下,I/O瓶颈与提取的数据量和提取次数有关。例如,一次读取一个字节的效率不如读取一块字节。

另一个与I/O相关的瓶颈是输入请求之间的持续时间。I/O设备更喜欢不间断地保持流式数据。一些输入设备,如硬盘驱动器,在接收到请求和数据开始传输之间有一段开销时间。对于硬盘驱动器,这将是磁盘加速时间。

您的最佳性能是不要浪费开发时间来干扰C或C++库。您需要使用硬件辅助。一些平台有一种称为直接内存访问控制器(DMA)的设备。该设备可以在不使用CPU的情况下从输入源获取数据并将其传送到内存。CPU可以在DMA传输数据的同时执行指令。为了使用硬件辅助,您需要在操作系统驱动程序级别编写代码,或者直接访问操作系统驱动。

C和C++I/O库是为一个称为流的独立于平台的概念而设计的。可能存在与此相关的执行开销(例如额外的缓冲)。如果你不关心不同的平台,那么直接访问操作系统驱动程序。

不要把时间浪费在C和C++库上。在那里没有太多的性能提升。更高的性能在于直接访问操作系统驱动程序(或使用自己的驱动程序)。访问I/O的方式和时间将显示出比调整C和C++库更大的性能提升。

最后,有效地使用处理器数据缓存也可以提高性能。

最新更新