【问题标题】:Performance of copying a file with fread/fwrite to USB使用 fread/fwrite 将文件复制到 USB 的性能
【发布时间】:2012-01-21 13:18:00
【问题描述】:

我前面有一段代码,它将文件复制到 USB 设备。 以下部分是重要的:

while((bytesRead = fread(buf, 1, 16*1024, m_hSource)) && !bAbort) {
    // write to target
    long bytesWritten = fwrite(buf, 1, bytesRead, m_hTarget);

    m_lBytesCopied += bytesWritten;

这个东西,客户说,与普通电脑usb 速度相比,它相当慢。我没有编写代码,所以优化是我的工作。

所以我想知道,首先读取完整文件然后一步写入文件是否是一种更好的方法。但我不知道这有多容易出错。 代码还会在每个复制步骤之后检查所有字节是否正确写入,这样也可能会减慢进程。

我不是那个 c++ 和硬件专家,所以我问你们,我怎样才能加快速度并保持复制成功。

【问题讨论】:

  • 在别处寻找瓶颈。更改缓冲区大小可能会有所改善,但您的问题可能是其他问题。
  • 嗯,这是解决这个特殊问题的唯一部分。所以只能是代码。
  • 删除字节写入正确的检查。如果您不能信任第一次写入,那么您将无法信任用于验证的以下读取。 (我假设您正在检查 bytesWritten 是否有错误。)
  • 发布的代码在性能方面看起来不错。您未发布的代码部分中是否有任何可能导致问题的内容?
  • 所以,也许该设备被识别为 USB 1.1 设备。 USB 1 太慢了..

标签: c++ c


【解决方案1】:
  1. 尝试大块读/写。 16M、32M的拷贝文件还不错。
  2. 如果您只是想要复制文件,您可以随时调用system(),这样会更快。
  3. 代码还会在每个复制步骤之后检查所有字节是否正确写入,这样也可能会减慢进程。

    您可以通过创建较大块的 散列 来检查它。就像将文件分成 64M 块一样。然后匹配这些块的哈希。 Bittorrent 协议有此功能。

  4. 如果您有 mmap 或 MapViewOfFile 可用,请先映射文件。然后写入usb。这样读取操作将由内核处理。

  5. Kerrek 刚刚评论了在 mmap 上使用 memcpy。 memcpy 和 2 个mmaped 文件 看起来很棒。

另请注意,最新的操作系统在移除 USB 记忆棒时会写入数据。在删除之前,它只是将数据写入缓存。所以从操作系统复制可能会更快。

【讨论】:

  • @KerrekSB +1。 memcpy 和 2 个 mmaped 文件似乎是一个不错的选择。更新了我的问题。
【解决方案2】:

读写重叠怎么办?

在当前代码中,总时间为time(read original) + time(write copy),如果您读取第一个块,则在写入时开始读取第二个块,依此类推。您的总时间为max(time(read original), time(write copy))(加上读/写时间不会流水线的第一个和最后一个块)。

如果阅读和写作时间大致相同,则几乎可以节省一半时间。

您可以使用两个线程或异步 IO 来完成。不幸的是,线程和异步 IO 依赖于平台,因此您必须查看系统手册或选择合适的可移植库。

【讨论】:

  • AFAIK,USB I/O 也主要依赖于平台,不是吗?
  • @AndréCaron 如果您正在构建驱动程序,我想是的,但在这种情况下,我认为它只是访问文件系统,因此您可以 fopen 文件(这是标准的)。
【解决方案3】:

我只会使用一些特定于操作系统的函数,这些函数肯定会比仅使用 c/c++ 函数编写的任何东西更快。

对于 Linux,这可能是 sendfile 函数。对于 Windows,CopyFile 将完成这项工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-28
    • 2012-02-29
    • 2013-02-11
    • 1970-01-01
    相关资源
    最近更新 更多