Правильный ли подход к отображению всего большого файла для обработки, и вопрос производительности в MPI - PullRequest
2 голосов
/ 14 апреля 2019

Я пытаюсь обрабатывать большой файл JSON (около 10 ГБ) построчно, используя MPI в python. Подход, который я использовал, заключался в разделении линий между всеми доступными процессами, и каждый процесс имел дело только со строками, которые соответствуют его ранговому номеру.

comm = MPI.COMM_WORLD
size = comm.Get_size()
rank = comm.Get_rank()

with open(path, 'r') as f:

    for index, line in enumerate(f):
        if index % size == rank:
            #do some process with line
    comm.Barrier()
# do MPI reduction on results from all the processes

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

with open(path, 'r') as f:

    mm = mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ)
    for index, line in enumerate(iter(mm.readline, b'')):
        if index % size == rank:
            #do some process with line
    comm.Barrier()
    mm.close()
# do MPI reduction on results from all the processes

Я запустил код в удаленной системе HPC с другими ресурсами, например, 1 узел 1 задача, 1 узел 8 задач и 2 узла 8 задач (по 4 задачи на узел). Результаты действительно улучшились во всех случаях по сравнению со стандартным вводом / выводом. Время выполнения в среднем на 20 секунд короче.

У меня два вопроса:

Во-первых, поскольку у меня ограниченные знания в области ввода-вывода, виртуальной памяти и т. Д., Мне интересно, является ли это несколько «правильным» подходом к обработке большого файла? Я узнал, что mmap использует виртуальное адресное пространство для сопоставления файла с диска. Означает ли это, что до тех пор, пока виртуальное адресное пространство может вместить весь файл, проблем в этом нет?

Во-вторых, результаты задач 2 узлов 8, как правило, выполняются быстрее, чем задачи 1 узла 8. Сначала я подумал, что должно быть наоборот, так как 1 узел означает меньшую нагрузку на связь между процессами. Теперь я думаю, что в моей программе не так много общения. Вместо этого 2 узла означает отдельный ввод / вывод в каждом узле, что приводит к более высокой скорости Правильно ли мое предположение или могут быть какие-то другие причины?

...