【问题标题】:Which USB read pattern is more efficient: Multiple reads or one big read?哪种 USB 读取模式更有效:多次读取还是一次大读取?
【发布时间】:2019-09-18 19:55:59
【问题描述】:

对于通过 USB 传输数据并将其写入内存以供进一步处理,哪一个更有效(= 最快)实现:

  1. 从 USB 读取少量数据并多次重复写入内存。
  2. 从 USB 读取大量数据并将其写入内存。

【问题讨论】:

  • 从历史上看,对于硬盘来说,读写底层硬件大小的块并在块边界处对齐是最好的。将数据写入硬件块的一部分有时需要读取整个块,更新内存缓冲区并将整个块写回。现代硬件和(设备驱动程序)软件努力减少这些与块相关的开销。
  • @AdrianHHH IO 开销呢? IO 开销是否超过内存写入开销?
  • @AdrianHHH 将数据写入硬件块的一部分有时需要读取整个块,更新内存缓冲区并将整个块写回。仍然如此。将四个字节写入使用 2048 字节块的磁盘,并且必须读取、修改整个块并将其写回磁盘。 现代硬件和(设备驱动程序)软件努力减少这些与块相关的开销。 而且它通常做得很好 - 但如果你想以或接近其设计限制运行系统,你可以'不要抽象,也不要忽略实际的设计。
  • 你能用mmap()吗?
  • “高效”在什么意义上?潜伏?吞吐量?能源使用? USB设备磨损?

标签: c performance memory usb coding-efficiency


【解决方案1】:

RAM 访问总是 (*) 比真正的磁盘访问快...

时间取决于您的硬件,但对于少量数据,RAM 访问时间为 ns,而 USB 访问时间范围为数十微秒到毫秒。不过,这并不特定于 USB:RAM 访问比 SSD 访问更快。与 USB 访问相比,这更是如此。

另一个值得注意的有趣的事情是访问时间与数据的大小不成比例。对于前兆字节尤其如此(部分是由于缓存)。因此,您一次阅读的内容越多,您的表现就会越好。

最后,当您的数据存储在 RAM 中时,会缓存最常用的数据,从而缩短延迟时间。

因此,只要有可能,您应该立即读取数据并将其存储在 RAM 中以供后续访问。

(*) 此规则的唯一限制是您的 RAM 大小。如果您的计算机使用了更多的 RAM 内存,那么额外的数据将被交换,也就是说,访问最少的数据将被传输到您的物理磁盘并在需要时检索。这显然会导致灾难性的表现。

总之,一次读取大量数据,但不会超过 RAM 中的空间来存储它。一次读取超过 1G 不会显着提高性能,只会造成麻烦。

【讨论】:

  • OP 没有提到任何“磁盘”; OP 的系统可能甚至没有磁盘。
  • @einpoklum 哎呀,我在考虑 USB,但我写了 HDD。已更正。
【解决方案2】:

根据我的经验,最好从 USB 读取大量数据以减少操作系统的延迟。 很久以前,我正在编写一个应用程序,该应用程序必须在原始模式下使用 USB 将数据写入设备。该设备使用 128 字节数组来存储来自另一部分的数据(在我的例子中是 Windows)。当我增加设备部分的数据大小时,分配 1 MB 的空间,我得到了很大的性能提升

【讨论】:

    【解决方案3】:
    1. 从 USB 读取少量数据并多次重复写入内存。
    2. 从 USB 读取大量数据并将其写入内存。

    您应该记住,拥有内存引用总是最快。绝对没有竞争,但是,在内存方面,始终在内存中拥有大量数据可能并不总是理想的。

    在您的两个问题中,第二个选项不仅最适合快速访问,而且最适合清洁。它将显着减少获取数据的 i/o 流的数量。

    打开和关闭次数过多的问题(如果您选择第一个选项将是一个问题)会导致磁盘阻塞,直到可以刷新所有数据(每次关闭时)。这不仅会损害磁盘缓存机制,而且 IO 会一直阻塞,直到它可以一遍又一遍地完成。这可能会导致更长的时间。

    除非您绝对必须使用 1,否则 2 通常是更好的选择。然而,与往常一样,最好的检查方法是进行基准测试。对你有用的东西可能对其他人不起作用。

    这个 stackoverflow 讨论可能会让您感兴趣,它不是明确地关于 C(而是它的 C++),但是基本思想是相同的:Many small files or one big file? (Or, Overhead of opening and closing file handles) (C++)

    【讨论】:

      【解决方案4】:

      这完全取决于您对性能的定义。如果您想尽快从 USB 中获取数据,那么一次大读取就可以解决问题。

      但是,一次大读取可能会导致错误或成为阻塞操作。通常进行多次小读取将允许您在发生错误时重试部分读取,并且还允许您在完成部分读取时更新 ui。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-10-11
        • 1970-01-01
        • 1970-01-01
        • 2012-07-15
        • 1970-01-01
        • 2011-09-18
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多