当前位置:  开发笔记 > 编程语言 > 正文

并行文件写入是否有效?

如何解决《并行文件写入是否有效?》经验,为你挑选了1个好方法。

我想知道并行文件写入是否有效.实际上,硬盘一次只有一个可用的读头.因此,HDD可以一次完成一项任务.但是下面的测试(在python中)与我的预期相矛盾:

要复制的文件大约是1 Gb

脚本1(//逐行读取和写入10次相同文件的任务):

#!/usr/bin/env python
from multiprocessing import Pool
def read_and_write( copy_filename ):
    with open( "/env/cns/bigtmp1/ERR000916_2.fastq", "r") as fori:
        with open( "/env/cns/bigtmp1/{}.fastq".format( copy_filename) , "w" ) as fout:
            for line in fori:
                fout.write( line + "\n" )
    return copy_filename

def main():
    f_names = [ "test_jm_{}".format(i) for i in range( 0, 10 ) ]
    pool = Pool(processes=4)
    results = pool.map( read_and_write, f_names )

if __name__ == "__main__":
    main()

脚本2(逐行读取和写入10次同一文件的任务):

#!/usr/bin/env python
def read_and_write( copy_filename ):
    with open( "/env/cns/bigtmp1/ERR000916_2.fastq", "r") as fori:
        with open( "/env/cns/bigtmp1/{}.fastq".format( copy_filename) , "w" ) as fout:
            for line in fori:
                fout.write( line + "\n" )
    return copy_filename

def main():
    f_names = [ "test_jm_{}".format(i) for i in range( 0, 10 ) ]
    for n in f_names:
        result = read_and_write( n )

if __name__ == "__main__":
    main()

脚本3(//将同一文件复制10次的任务):

#!/usr/bin/env python
from shutil import copyfile
from multiprocessing import Pool
def read_and_write( copy_filename ):
    copyfile( "/env/cns/bigtmp1/ERR000916_2.fastq", "/env/cns/bigtmp1/{}.fastq".format( copy_filename) )
    return copy_filename

def main():
    f_names = [ "test_jm_{}".format(i) for i in range( 0, 10 ) ]
    pool = Pool(processes=4)
    results = pool.map( read_and_write, f_names )

if __name__ == "__main__":
    main()

脚本4(任务复制10次同一文件):

#!/usr/bin/env python
from shutil import copyfile
def read_and_write( copy_filename ):
    copyfile( "/env/cns/bigtmp1/ERR000916_2.fastq", "/env/cns/bigtmp1/{}.fastq".format( copy_filename) )
    return copy_filename

def main():
    f_names = [ "test_jm_{}".format(i) for i in range( 0, 10 ) ]
    for n in f_names:
        result = read_and_write( n )

if __name__ == "__main__":
    main()

结果:

$ # // task to read and write line by line 10 times a same file
$ time python read_write_1.py

real    1m46.484s
user    3m40.865s
sys 0m29.455s

$ rm test_jm*
$ # task to read and write line by line 10 times a same file
$ time python read_write_2.py

real    4m16.530s
user    3m41.303s
sys 0m24.032s

$ rm test_jm*
$ # // task to copy 10 times a same file
$ time python read_write_3.py

real    1m35.890s
user    0m10.615s
sys 0m36.361s


$ rm test_jm*
$ # task to copy 10 times a same file
$ time python read_write_4.py

real    1m40.660s
user    0m7.322s
sys 0m25.020s
$ rm test_jm*

这些基础结果似乎表明//读取和写入更有效.

谢谢你的光



1> Danny_ds..:

我想知道并行文件写入是否有效.

简短回答:从多个线程同时物理地写入同一磁盘,永远不会比从一个线程写入该磁盘更快(这里谈论普通硬盘).在某些情况下,它甚至可能会慢很多.

但是,一如既往,它取决于很多因素:

操作系统磁盘缓存:写操作通常由操作系统保存在缓存中,然后以块的形式写入磁盘.因此,多个线程可以同时写入该缓存而不会出现问题,并且具有速度优势.特别是如果数据的处理/准备花费的时间长于磁盘的写入速度.

在某些情况下,即使从多个线程直接写入物理磁盘,操作系统也会对此进行优化,并且只为每个文件写入大块.

然而,在最坏的情况下,每次都可以将较小的块写入磁盘,从而导致需要在每个文件交换机上进行硬盘搜索(正常硬盘上为±10ms!)(在SSD上执行相同操作)是如此糟糕,因为有更多的直接访问,不需要寻求).

因此,一般情况下,当同时从多个线程写入磁盘时,最好在内存中准备(某些)数据,并使用某种锁定将最终数据写入更大的块中,或者从一个专用中写入作家线程.如果文件在写入时正在增长(即前面没有设置文件大小),则将数据写入较大的块也可以防止磁盘碎片(至少尽可能多).

在某些系统上可能没有任何区别,但在其他系统上它可以产生很大的差异,并且变得慢得多(甚至在具有不同硬盘的同一系统上).

要使用单个线程与多个线程对写入速度的差异进行良好测试,总文件大小必须大于可用内存 - 或者至少应在测量结束时间之前将所有缓冲区刷新到磁盘.仅测量将数据写入OS磁盘高速缓存所花费的时间在这里没有多大意义.

理想情况下,将所有数据写入磁盘所测量的总时间应等于物理硬盘写入速度.如果使用一个线程写入磁盘比磁盘写入速度慢(这意味着处理数据所需的时间比写入更长),显然使用更多线程会加快速度.如果从多个线程写入变得比磁盘写入速度慢,则在不同文件(或同一大文件内的不同块)之间切换导致的磁盘搜索时间将丢失.

为了了解执行大量磁盘搜索时的时间损失,让我们看看一些数字:

比如说,我们有一个写入速度为50MB/s的硬盘:

写一个50MB的连续块需要1秒钟(理想情况下).

在1MB的块中执行相同的操作,使用文件切换和在其间产生的磁盘搜索将给出:20ms写入1MB + 10ms寻道时间.写50MB需要1.5秒.这是一个50%的时间增加,只是在两者之间进行快速搜索(同样适用于从磁盘读取 - 考虑到更快的读取速度,差异甚至会更大).

实际上它将介于两者之间,具体取决于系统.

虽然我们希望操作系统能够很好地处理所有这些(或者通过使用IOCP),但情况并非总是如此.

推荐阅读
手机用户2502851955
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有