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