提高高速文件复制的写入速度?

我一直在尝试找出编写文件复制例程的最快方法,将大文件复制到RAID 5硬件上。 平均文件大小约为2 GB。 有2个窗口框(都运行win2k3)。第一个框是源,大文件位于何处。第二个盒子有一个RAID 5存储。 http://blogs.technet.com/askperf/archive/2007/05/08/slow-large-file-copy-issues.aspx 以上链接清楚地解释了为什么Windows复制,robocopy和其他常见的复制实用程序在写入性能方面受到影响。 因此,我编写了一个使用CreateFile,ReadFile& S的C / C ++程序。 WriteFile API与
NO_BUFFERING
&
WRITE_THROUGH
旗帜。该程序模拟ESEUTIL.exe,从某种意义上说,它使用2个线程,一个用于读取,一个用于写入。读取器线程从源读取256 KB并填充缓冲区。一旦填充了16个这样的256 KB块,写入器线程就会将缓冲区中的内容写入目标文件。如您所见,编写器线程在一次写入中写入8MB的数据。该程序分配32个这样的8MB块...因此,写入和读取可以并行发生。 可以在上面的链接中找到ESEUtil.exe的详细信息。 注意:使用
NO_BUFFERING
时,我正在处理数据对齐问题。 我使用像ATTO这样的台式标记实用程序,发现我们的RAID 5硬件在写入8MB数据块时的写入速度为每秒44MB。每分钟大约2.57 GB。 但我的程序每分钟只能达到1.4 GB。 有谁可以帮我确定问题是什么?是否有更快的API其他
CreateFile
ReadFile
WriteFile
可用?     
已邀请:
您应该使用异步IO来获得最佳性能。那是用
FILE_FLAG_OVERLAPPED
打开文件并使用WriteFile的
LPOVERLAPPED
参数。使用
FILE_FLAG_NO_BUFFERING
可能会或可能不会获得更好的性能。你将不得不测试看看。
FILE_FLAG_NO_BUFFERING
通常会为您提供更加一致的速度和更好的流式传输行为,并且它可以避免使用您可能不再需要的数据来污染磁盘缓存,但总体上不一定更快。 您还应该测试以查看每个IO块的最佳大小。根据我的经验,一次复制4k文件和一次复制1Mb文件之间存在巨大的性能差异。 在我过去对此(几年前)的测试中,我发现大小低于64kB的块大小由开销占主导地位,并且总吞吐量继续提高,块大小增加到大约512KB。如果使用今天的驱动器,您需要使用大于1MB的块大小来获得最大吞吐量,我不会感到惊讶。 您当前使用的数字似乎是合理的,但可能不是最佳的。另外我很确定FILE_FLAG_WRITE_THROUGH可以防止使用磁盘缓存,因此会花费你一些性能。 您还需要注意,使用CreateFile / WriteFile复制文件不会在NTFS上复制时间戳或备用数据流等元数据。你必须自己处理这些事情。 实际上用你自己的代码替换
CopyFile
是相当多的工作。 附录: 我应该提一下,当我在WindowsNT 3.0(大约10年前)上使用软件Raid 0进行尝试时。速度对缓冲区内存的对齐非常敏感。事实证明,当DMA超过16个物理内存区域(64Kb)时,SCSI驱动程序必须使用特殊算法从分散/收集列表中执行DMA。要获得保证的最佳性能,需要物理上连续的分配 - 这是只有驱动程序才能请求的。这基本上是当时流行芯片组的DMA控制器中的一个错误的解决方法,并且不太可能仍然是一个问题。 但是 - 我仍然强烈建议您测试从32kb到32Mb的2个块大小的所有功率,以查看哪个更快。您可能会考虑测试一下缓冲区是否始终比其他缓冲区更快 - 这并非闻所未闻。     
前段时间我写了一篇关于异步文件I / O的博客文章,以及它往往最终会实现同步,除非你做的一切都是正确的(http://www.lenholgate.com/blog/2008/02/when-是异步文件的写,而不是-asynchronous.html)。 关键点是即使你使用
FILE_FLAG_OVERLAPPED
FILE_FLAG_NO_BUFFERING
,你仍然需要预先扩展文件,这样你的异步写入就不需要像文件那样扩展文件了。出于安全原因,文件扩展名始终是同步的要预先扩展,您需要执行以下操作: 启用
SE_MANAGE_VOLUME_NAME
权限。 打开文件。 用
SetFilePointerEx()
寻找所需的文件长度。 用
SetEndOfFile()
设置文件结尾。 在文件
SetFileValidData()
中设置有效数据的结尾。 关闭文件。 然后... 打开要写的文件。 发出写入     
如果不写目的地,您可以多快读取源文件? 源文件是否碎片化?片段化读取比连续读取慢一个数量级。您可以使用“contig”实用程序使其连续: http://technet.microsoft.com/en-us/sysinternals/bb897428.aspx 连接两台机器的网络有多快? 您是否尝试过编写虚拟数据,而不是像ATTO那样先读取它? 您一次在飞行中有多个读写请求吗? RAID-5阵列的条带大小是多少?一次写一个完整的条带是写入RAID-5的最快方法。     
请记住,硬盘可以缓冲来自盘片的数据并进入盘片。大多数磁盘驱动器将尝试优化读取请求以保持磁盘旋转并最小化磁头移动。在写入盘片之前,驱动器会尝试从主机吸收尽可能多的数据,以便尽快断开主机的连接。 您的性能还取决于PC上的I / O总线流量以及磁盘和主机之间的流量。还有其他需要考虑的替代因素,例如系统任务和“同时”运行的程序。您可能无法获得与测量工具相同的精确性能。请记住,由于上述开销,这些时序存在误差因素。 如果您的平台有DMA控制器,请尝试使用它们。     
如果写入速度很重要,为什么不考虑RAID 0用于硬件配置? 客户想要RAID 5。 由于更好的容错能力,优先于RAID 0。 客户对RAID 5可以提供的内容感到满意。这个问题 这里使用ATTO对硬件进行基准测试,显示每分钟2.57 GB的写入速度(8MB 大块写),为什么复制工具无法实现接近呢?像每个2 GB的东西 min是我们正在关注的。到目前为止,我们每分钟只能达到~1.5 GB。     
正确的方法是使用非缓冲的完全异步I / O.您将需要发出多个I / O以保持队列运行。这使文件系统,驱动程序和Raid-5子系统能够更好地管理I / O. 您还可以打开多个文件,并向多个文件发出读取和输入。 注意!优秀的I / O数量以及交错读写方式将在很大程度上取决于存储子系统本身。您的程序需要高度重要,以便您可以调整它。 注意 - 我相信Robocopy已得到改进 - 你试过吗?一世     
我做了一些测试并得到了一些结果。 测试在100Mbps和100Mbps上进行。 1Gbps网卡。源计算机是Win2K3服务器(SATA),目标计算机是Win2k3服务器(RAID 5)。 我跑了3个测试: 1)网络阅读器 - >该程序只是通过网络读取文件。该程序的目的是找到最大的n / w读取速度。我正在使用CreateFile&amp ;;执行非BUFFERED读取ReadFile的。 2)Disk Writer - >该程序通过写入数据对RAID 5速度进行基准测试。非BUFFERED写入使用CreateFile& amp; WriteFile的。 3)闪电战复制 - >该程序是文件复制引擎。它通过网络复制文件。最初的问题讨论了该程序的逻辑。我正在使用带有NO_BUFFERING的同步I / O读取&写。使用的API是CreateFile,ReadFile& WriteFile的。 以下是结果: 网络读者: - 100 Mbps网卡 获得148344毫秒读取768 MB,块大小为8 KB。 花了89359毫秒读取768 MB,块大小为64 KB 获取82625毫秒读取768 MB,块大小为128 KB 获得79594毫秒读取768 MB,块大小为256 KB 读取78687毫秒读取768 MB,块大小为512 KB 读取79078毫秒,读取768 MB,块大小为1024 KB 花了78594毫秒读取768 MB,块大小为2048 KB 获得78406毫秒读取768 MB,块大小为4096 KB 读取78281 ms,读取768 MB,块大小为8192 KB 1 Gbps网卡 花了206203毫秒读取5120 MB(5GB),块大小为8 KB 读取77860 ms以读取5120 MB,块大小为64 KB 读取74531 ms以读取5120 MB,块大小为128 KB 获得68656毫秒读取5120 MB,块大小为256 KB 读取64922 ms以读取5120 MB,块大小为512 KB 花了66312毫秒读取5120 MB,块大小为1024 KB 获得68688毫秒读取5120 MB,块大小为2048 KB 读取64922 ms以读取5120 MB,块大小为4096 KB 获取66047毫秒读取5120 MB,块大小为8192 KB 磁盘写手: - 写入在RAID 5上执行NO_BUFFERING& WRITE_THROUGH 写入大小为4MB的2048MB(2GB)数据需要68328ms。 写入大小为8MB的2048MB数据需要55985ms。 写入块大小为16MB的2048MB数据需要49569ms。 写入大小为32MB的2048MB数据需要47281ms。 在RAID 5上执行写入仅使用NO_BUFFERING 写入大小为4MB的2048MB(2GB)数据需要57484ms。 写入大小为8MB的2048MB数据需要52594ms。 以16MB的块大小写入2048MB的数据需要49125ms。 写入块大小为32MB的2048MB数据需要46360ms。 随着块大小的减小,写性能会线性降低。 WRITE_THROUGH标志引入了一些性能损失 BLITZ COPY: - 1 Gbps NIC,使用NO_BUFFERING复制60 GB的文件 完成复制的时间:2236735毫秒。即,37.2分钟。 速度约为97 GB /每。 100 Mbps NIC,使用NO_BUFFERING复制60 GB的文件 完成复制的时间:7337219 ms。即,122分钟。 速度约为30 GB /每秒。 我尝试使用Jeffrey Ritcher的10-FileCopy程序,该程序使用Async-IO和NO_BUFFERING。但是,结果很差。我想原因可能是块大小为256 KB ...在RAID 5上写入256 KB非常慢。 与robocopy相比: 100 Mbps NIC:Blitz Copy和robocopy每小时执行@ ~30 GB。 1 GBps网卡:闪电战复制每小时@~97 GB,而robocopy @每小时50 GB。     

要回复问题请先登录注册