从硬盘读取文件时,mmap 通常被认为是快速将数据放入内存的好方法。使用光驱时,访问需要更多时间,并且您需要担心更高的延迟。您使用什么方法/抽象来隐藏/消除尽可能多的延迟和/或光驱的整体加载时间?
5 回答
通过从几个文件(最好是一个)顺序读取大量数据来最小化或消除搜索。
首先您必须记住,现代光驱读取顺序数据的速度非常快,但查找数据的速度仍然比 HD 慢很多。因此,如果您必须在一个大文件中搜索很多内容(例如,在 500+ MB 文件中随机跳转),首先将整个 500 MB 复制到 HD(到一个临时文件中)实际上可能会更快,这将在顺序,快速读取,对临时文件执行操作(速度快得多,因为 HD 上的访问时间要快得多)并在完成后再次删除文件。
以上同样适用于小文件和许多小文件。处理几个大文件比处理许多小文件要快得多,因为每次你从一个小文件切换到另一个文件时,巨大的搜索时间会让你再次头疼。这就是为什么许多在光学媒体上发布的游戏将游戏数据打包在巨大的存档文件中(例如,一个级别的所有纹理都在一个大文件中,而不是每个纹理只有一个小文件),因此请尝试在大文件中保持数据结构良好您可以尽可能按顺序阅读。
高清缓存本身就是一种很好的技术。我记得有一个游戏,虽然我忘记了标题,它总是将你环境的 3D 数据保持在 HD 上。当您在世界各地移动时,它不断地将数据从 DVD 复制到 HD。因此,周围的 3D 景观总是可以在 HD 上快速访问,但不会复制整个 DVD,只有大约 200-300 MB 临时缓存在 HD 上以节省 HD 空间。唯一令人讨厌的是,您在玩游戏时经常有 DVD 访问“噪音”,但大部分时间整个过程只发生在 CPU 空闲时间,所以它并没有真正影响游戏。只有当您在同一方向上持续快速奔跑时,DVD 驱动器才可能出现回落,并且游戏突然停止并显示加载指示器几秒钟。但是我玩这个游戏已经好几天了,可能在一周内看到这个加载指示器三次。如果您移动缓慢或不经常向同一方向移动,则永远不会有加载指示器。
您无法使用真正的抽象。光驱具有非常特殊的特性,必须针对这些特性进行优化以获得最佳性能。
一些技巧:
光驱的最大杀手是寻道时间。在可能的情况下,确保您正在阅读的所有文件在光盘上都是连续的,并且尽可能紧密地打包。如果你必须寻求,那么就向一个方向寻求,并且尽可能不频繁地寻求。
异步读取还可以大幅提升性能。如果您需要加载和处理文件 A、B 和 C,那么在处理 A 之前,您应该开始读取文件 B,而在处理 B 时,您应该读取文件 C,依此类推。
一般来说,你可以一次读取的数据越多越好,例如避免大量的小读取()。在读取大量数据时,您只能获得光盘的理论吞吐量。一些操作系统的/驱动程序将通过缓存扇区将读取大量小文件的损失降到最低,有些则不会。
对仅缓存部分 TOC 的某些文件系统/操作系统进行大量存在(文件名)检查也可能是有害的。
在我们的应用程序中,我们通常将文件打包成一个或多个“集总”文件,并根据它们的访问顺序对它们进行排序。一些文件(和目录)在被解压到内存中之前会被完整地压缩和读取。如果您有一个包含大量小文件(例如 XML 或脚本)的目录,这将是一个胜利。
基本上有很多基准测试和调整:)
慢车会变慢。对不起。但是,光驱硬件通常会进行优化以进行顺序读取,因此如果您可以让您的代码以这种方式工作,您可能会看到一些改进。mmap()
我怀疑您会看到, fread()
, et al之间的顺序访问有很大区别。如果您的操作系统尚未为您执行此操作,您还可以将读取缓冲区大小调整为驱动器块大小的倍数。与硬盘驱动器相比,光驱的块大小可能更大,如果您的缓冲区不够大,您就要付出代价。
我不确定在您阅读它时您可以做很多事情。您可以查看创建文件 API——您可以向 Windows 传递一些提示,告诉它您正在为顺序或随机访问打开文件。这应该允许 Windows 优化用于文件的缓存策略。
您可以调整读取文件时咬掉的“块”,以使它们更大或更小。如果您读取的块是磁盘上分配单元大小的倍数,您可能会得到轻微的改进。
硬件和媒体可以发挥作用。假设您有一个读取速度为 16 倍的 DVD 驱动器。它将需要额定为 16 倍或更高的媒体,并且某些驱动器不适用于某些媒体品牌。因此,即使媒体符合评级,您也可能不会以最大速度阅读。(通常对光驱进行良好的硬件审查会包括这样的细节)。
光盘上文件的布局可能很重要。一下子就烧完了?它是否只是作为磁盘安装(如数据包模式 R/W?)。我没有这方面的经验,但鉴于光驱上的寻道时间较长,碎片文件可能比现代硬盘产生更大的影响。