我正在运行cat
以单独file_X
与大量文件组合file_1
,例如file_100000000000
.
由于数量众多,我将作业分配到一个有 64 个 CPU 的节点上,以便在每个 CPU 上并行运行。每个作业都在一个子文件夹中运行,因此有 64 个子文件夹。
令我惊讶的是,整体速度比预期的要慢得多。
由于我使用的shell脚本只是将每个作业指向file_X
位于64个子文件夹的父目录中的同一个文件,我想知道如果多个CPU同时读取同一个文件,会减慢每个CPU的读取速度吗?
我正在运行cat
以单独file_X
与大量文件组合file_1
,例如file_100000000000
.
由于数量众多,我将作业分配到一个有 64 个 CPU 的节点上,以便在每个 CPU 上并行运行。每个作业都在一个子文件夹中运行,因此有 64 个子文件夹。
令我惊讶的是,整体速度比预期的要慢得多。
由于我使用的shell脚本只是将每个作业指向file_X
位于64个子文件夹的父目录中的同一个文件,我想知道如果多个CPU同时读取同一个文件,会减慢每个CPU的读取速度吗?
是和不是。
无论有多少处理器在执行此操作,文件的实际读取都应该以相同的速度发生。
但是,根据操作系统及其配置,可能会发生文件锁定。虽然多个进程可以同时拥有一个读锁,但获取锁和释放该锁必须发生在共享互斥块中。如果您的系统正在执行这些类型的锁定,则处理器必须排队以访问文件,然后必须排队以声明他们对文件缺乏进一步的兴趣。
根据存储 file_X 的文件系统和与之组合的各种文件以及挂载该文件系统的选项,每次 cat 读取 file_X 时,它的访问时间可能会更新。如果是这种情况,很可能会在每次更新之前对 file_X inode 进行写锁定,然后将其释放。
速度降低的另一个可能原因是所有 64 个作业都在并行写入文件,这些文件必然位于磁盘上的不同点上。除非您使用的是固态驱动器 (SSD),否则可能需要在磁盘上大量移动写入头。这些文件位于 64 个不同的目录中,因此除了正在创建的文件之外,还有 64 个位置需要更新。
在 shell 脚本中执行所有这些活动意味着每个文件副本都是分叉执行的。Fork 被视为一个相当昂贵的系统调用,但在具有共享库的系统上,与 exec 系列系统调用的成本相比,它相形见绌,因为这需要搜索每个共享库,并加载所有共享库图书馆。这是另一个可能在文件上放置读锁的地方,具体取决于它所在的 unix 以及它的配置可能是什么。