Мне кажется, что ваша задача должна получить выгоду от нескольких потоков выполнения (процессов или потоков), так как она, кажется, имеет очень грубое сочетание ввода-вывода и процессора. Я ожидал бы ускорения в несколько раз, но трудно сказать, не зная деталей. Предлагаю попробовать.
Один из способов - разбить список файлов на группы, если есть несколько ядер, которые вы можете сэкономить. Затем обработайте каждую группу в fork
, который собирает ее результаты и передает их обратно в родительский узел после передачи по каналу или файлам. Есть модули, которые делают это и многое другое, например, Forks :: Super или Parallel :: ForkManager . Они также предлагают очередь, еще один подход, который вы можете использовать.
Я делаю это регулярно, когда задействовано много данных в файлах, и почти линейное ускорение увеличивается до 4 или 5 ядер (в NFS) или даже с большим количеством ядер в зависимости от деталей задания и аппаратного обеспечения.
Я бы осторожно утверждал, что это может быть проще, чем потоки, поэтому попробуйте сначала.
Другим способом было бы создание очереди потока ( Thread :: Queue )
и накормить его именами групп. Обратите внимание, что потоки Perl не являются легкими "потоками" , как можно было бы ожидать; напротив, они тяжелые, они копируют все в каждый поток (поэтому запустите их заранее, пока в программе не было много данных), и у них есть и другие тонкости. Поэтому у вас есть небольшое количество рабочих с хорошим списком файлов для каждого, вместо множества потоков, быстро работающих с очередью.
В этом подходе также будьте осторожны с тем, как передавать результаты обратно, поскольку частое общение создает значительные накладные расходы для потоков (Perl), по моему опыту.
В любом случае важно, чтобы группы были сформированы таким образом, чтобы обеспечить сбалансированную рабочую нагрузку для каждого потока / процесса. Если это невозможно (вы можете не знать, какие файлы могут занимать намного больше времени, чем другие), тогда потоки должны брать меньшие партии, в то время как для вилок используется очередь из модуля.
Передача только файла или нескольких файлов потоку или процессу, скорее всего, слишком легкая рабочая нагрузка, и в этом случае накладные расходы на управление могут стереть (или обратить вспять) возможное увеличение скорости. Перекрытие ввода-вывода между потоками / процессами также увеличится, что является основным пределом для ускорения.
Оптимальное количество файлов для передачи в поток / процесс сложно оценить, даже если все детали под рукой; пытаться. Я предполагаю, что заявленная производительность (более 5 секунд для файла) обусловлена неэффективностью, которую можно устранить. Если какой-то файл действительно обрабатывает , что долго, то начните с передачи одного файла за раз в очередь.
Также, пожалуйста, внимательно рассмотрите ответ моба . И обратите внимание, что это передовые методы.
Практический комментарий: как отмечено в комментарии Шон , для извлечения нескольких фрагментов данных из 500 файлов требуется 45 минут, что выглядит довольно экстремально (если только используемый модуль не является крайне неэффективным ); Я бы дал самое большее несколько минут?
Поэтому сначала проверьте свой код на предмет неоправданной неэффективности.