2016-01-08 3 views
5

Я хотел бы знать, эффективна ли параллельная запись файлов. Действительно, на жестком диске есть одна удобная читаемая голова за раз. Таким образом, 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* 

Эти основы результаты кажется, показывают, что // ИО читать и писать более эффективным.

Спасибо вам зажигать

+2

Какие у вас есть данные для жесткого диска, имеющего одну прочитанную головку? –

+1

Любые данные, которые вы пишете в файл, просто будут сидеть в ОЗУ вашего компьютера, пока операционная система вашего компьютера не начнет сопоставлять его и на самом деле быстро записать на диск. – kindall

+0

Какие результаты вы ожидали? – AChampion

ответ

9

Я хотел бы знать, если параллельно запись файла является эффективной.

Короткий ответ: физически писать на тот же диск из нескольких потоков одновременно, никогда не будет быстрее, чем запись на этот диск из одного потока (говорить о нормальных жестких дисках здесь). В некоторых случаях это может быть намного медленнее.

Но, как всегда, это зависит от многих факторов: кэширование диска

  • OS: записи обычно хранится в кэше операционной системы, а затем записываются на диск в кусках. Таким образом, множество потоков могут одновременно записывать в этот кеш без проблем и иметь преимущество в скорости. Особенно, если обработка/подготовка данных занимает больше времени, чем скорость записи диска.

  • В некоторых случаях даже при записи непосредственно на физический диск из нескольких потоков ОС оптимизирует это и записывает только большие блоки в каждый файл.

  • В худшем случае, однако, меньшие блоки могут быть записаны на диск каждый раз, что приводит к необходимости поиска жесткого диска (± 10 мс на обычном hdd!) На каждом переключателе файлов (что делает то же самое на SSD не так уж плох, потому что есть более прямой доступ и не нужны никакие искажения).

Таким образом, в общем случае, при записи на диск из нескольких потоков одновременно, это могло бы быть хорошая идея, чтобы подготовить (некоторые) данные в памяти, и записывать окончательные данные на диск в больших блоках с помощью какого-то блокировку или, возможно, одну выделенную писатель-нить. Если файлы растут во время записи (т. Е.размер файла не установлен спереди), запись данных в больших блоках также может предотвратить фрагментацию диска (по крайней мере, насколько это возможно).

В некоторых системах может не быть никакой разницы, но на других это может иметь большое значение и стать намного медленнее (или даже в той же системе с разными жесткими дисками).

Чтобы иметь возможность проверить различия в скоростях записи с использованием одного потока или нескольких потоков, общий размер файлов должен быть больше, чем доступная память - или, по крайней мере, все буферы должны быть сброшены на диск перед измерением конца время. Измерение только времени, которое требуется для записи данных в кэш-память ОС, здесь не имеет особого смысла.

В идеале, общее время, затраченное на запись всех данных на диск, должно равняться скорости записи физического жесткого диска. Если запись на диск с использованием одного потока медленнее скорости записи на диске (это означает, что обработка данных занимает больше времени, чем запись), очевидно, что использование большего количества потоков ускорит процесс. Если запись из нескольких потоков становится медленнее, чем скорость записи на диске, время будет потеряно в образах дисков, вызванных переключением между разными файлами (или разными блоками внутри одного большого файла).

Чтобы получить представление о потери времени при выполнении много диска изыскивает, давайте посмотрим на некоторые цифры:

Say, у нас есть винчестер скорость записи 50MB/s:

  • Написание одного непрерывного блока 50 МБ займет 1 секунду (в идеальных условиях).

  • Выполнение такого же действия в блоках 1 МБ, с файловым переключателем и последующим обнаружением диска между ними: 20 мс для записи времени поиска 1 МБ + 10 мс. Написание 50 МБ займет 1,5 секунды. это на 50% больше времени, только чтобы сделать быстрый поиск между ними (то же самое относится и для чтения с диска - разница будет даже больше, учитывая более высокую скорость чтения).

В действительности это будет где-то посередине, в зависимости от системы.

Хотя мы могли бы надеяться, что ОС позаботится обо всем этом (или, например, используя IOCP), это не всегда так.

+0

Спасибо @danny_ds за ваш действительно полный ответ. Это было, хотя я: На данный момент я не знаю, как объяснить, что // io файла размером 1 ГБ, скопированного в 10 раз быстрее. Возможно, как вы объясните, у моего жесткого диска большой кеш. – bioinfornatics

+0

@bioinfornatics - я буду более внимательно смотреть на ваш код и данные, но хорошая мера заключается в том, что общая измеренная скорость записи должна быть равна физической скорости записи вашего hdd (т. Е. Делать не больше, чем копировать файл того же размер). Если у вас лучшие времена с использованием нескольких потоков, это почти наверняка означает, что время обработки занимает больше времени, чем время записи.Также убедитесь, что все данные сброшены на диск при измерении (общей) физической скорости записи. –

+0

@bioinfornatics - см. Мой обновленный ответ. Я вижу, что в ваших тестах вы используете один и тот же файл в цикле - так что все может быть в кеше. Тест также использует readline и writeline - это не самые быстрые способы записи данных на диск (и может быть медленнее, чем скорость записи на диске - не уверен). Другой (copy-) тест может быть: скопировать файл на диск (в 10 раз больше доступной памяти) и время его. Затем сделайте то же самое в 1 и в нескольких потоках. В обоих случаях старайтесь получить то же время, что и ручная копия. –

Смежные вопросы