假设您有一个整数文件,并且希望逐个读取它们。
您有两个缓冲选项。
-
声明大小为
N
的数组buffer
,并使用setvbuf
告诉fread
要使用哪个缓冲区。然后,当调用函数fread
读取整数时,您编写fread(&myInt, sizeof(myInt), 1, inputFile);
-
声明相同的数组
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++库更大的性能提升。
最后,有效地使用处理器数据缓存也可以提高性能。