我需要将数据写入驱动器。我有两个选择:
哪种方式更快?
我期望原始扇区写入功能_write更有效率。但是,我的测试结果失败了! fwrite更快。 _write花费更长的时间。
我已经粘贴了我的片段;也许我的代码是错的。你能帮我吗?无论哪种方式都可以,但我认为原始写入更好,因为看起来驱动器中的数据至少是加密的....
#define SSD_SECTOR_SIZE 512
int g_pSddDevHandle = _open("\\\\.\\G:",_O_RDWR | _O_BINARY, _S_IREAD | _S_IWRITE);
TIMER_START();
while (ulMovePointer < 1024 * 1024 * 1024)
{
_write(g_pSddDevHandle,szMemZero,SSD_SECTOR_SIZE);
ulMovePointer += SSD_SECTOR_SIZE;
}
TIMER_END();
TIMER_PRINT();
FILE * file = fopen("f:\\test.tmp","a+");
TIMER_START();
while (ulMovePointer < 1024 * 1024 * 1024)
{
fwrite(szMemZero,SSD_SECTOR_SIZE,1,file);
ulMovePointer += SSD_SECTOR_SIZE;
}
TIMER_END();
TIMER_PRINT();
答案 0 :(得分:18)
可能是因为没有缓冲直接写入。当您调用fwrite
时,您正在进行缓冲写入,这在大多数情况下往往更快。本质上,每个FILE*
处理程序都有一个内部缓冲区,当它变满时会定期刷新到磁盘,这意味着您最终会减少系统调用,因为您只能以更大的块写入磁盘。
换句话说,在第一个循环中,实际上是在每次迭代期间将SSD_SECTOR_SIZE字节写入磁盘。在你的第二个循环中,你不是。您只将SSD_SECTOR_SIZE字节写入内存缓冲区,根据缓冲区的大小,每隔N次迭代才会刷新一次。
答案 1 :(得分:6)
在_write()情况下,SSD_SECTOR_SIZE的值很重要。在fwrite情况下,每次写入的大小实际上是BUFSIZ。为了更好地进行比较,请确保底层缓冲区大小相同。
然而,这可能只是差异的一部分。
在fwrite案例中,您正在测量将数据存入内存的速度。您尚未将stdio缓冲区刷新到操作系统,并且您没有要求操作系统将其缓冲区刷新到物理存储。为了更准确地进行比较,您应该在停止计时器之前调用fflush()。
如果您真的关心将数据放入磁盘而不是仅将数据放入操作系统缓冲区,则应确保在停止计时器之前调用fsync()/ FlushFileBuffers()。
其他明显的差异:
驱动器不同。我不知道有多么不同。
写入设备的语义与写入文件系统的语义不同;允许文件系统延迟写入以提高性能,直到明确告知不要(例如,使用标准句柄,调用FlushFileBuffers());直接写入设备不一定以这种方式进行优化。另一方面,文件系统必须执行额外的I / O来管理元数据(块分配,目录条目等)
我怀疑你看到一个不同的政策,关于事物实际进入磁盘的速度有多快。原始磁盘性能可能非常快,但您需要大写入,最好是多个并发未完成的操作。您还可以在打开句柄时使用正确的选项来避免缓冲区复制。