Эффективная запись на Compact Flash в Python - PullRequest
2 голосов
/ 06 июля 2011

Я пишу графический интерфейс для выполнения прославленного «дд».

Я мог бы просто выполнить подпроцесс для 'dd', но я подумал, что с таким же успехом мог бы использовать open() / read() / write() для python, если бы я мог, так как это позволит мне гораздо легче отображать прогресс.

По запросу эта ссылка здесь у меня есть:

input = open('filename.img', 'rb')
output = open("/dev/sdc", 'wb')
while True:
    buffer = input.read(1024)
    if buffer:
        output.write(buffer)
    else:
        break
input.close()
output.close()

... однако это ужасно медленно. Или, по крайней мере, намного медленнее, чем dd. (примерно в 4-5 раз медленнее)

У меня была игра, и я заметил, что изменение количества «буферизованных» байтов сильно повлияло на скорость завершения. Например, повышение его до 2048 года наполовину заняло. Возможно, здесь будет OT для SO, но я полагаю, что флэш-память имеет оптимальное количество байтов для одновременной записи? Кто-нибудь может подсказать, как мне это узнать?

Изображение и карта имеют размер 1 Гб, поэтому я бы очень хотел вернуться к тем ~ 5 минутам, которые были потрачены, если это возможно. Я ценю это, по всей вероятности, я не буду соответствовать.

Вместо проб и ошибок, сможет ли кто-нибудь предложить способ оптимизации приведенного выше кода и обосновать, почему он работает? Особенно какое значение для input.read () например?

Одно ограничение: python 2.4.3 на Linux (centos5) (пожалуйста, не делайте мне больно)

Ответы [ 2 ]

1 голос
/ 06 июля 2011

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

Вы должны использовать утилиты time и strace, чтобы определить, почему ваша программа работает медленнее.Если time показывает большое user/real (большое значение больше 0.1), вы можете оптимизировать интерпретатор Python - cpython 2.4 работает довольно медленно, и вы все время создаете новые объекты вместо записи в предварительно выделенный буфер,Если существует значительная разница во времени sys, проанализируйте системные вызовы, сделанные обеими программами (с strace), и попытайтесь испустить те, которые dd делает.

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

0 голосов
/ 06 июля 2011

Итак, с небольшой помощью я полностью удалил бит буфера и добавил os.fsync().

import os

input = open('filename.img', 'rb')
output = open("/dev/sdc", 'wb')
output.write(input.read())
input.close()
output.close()
outputfile.flush()
os.fsync(outputfile.fileno())
...