Arhn - архитектура программирования

Как увеличить пропускную способность при обработке большого количества файлов

Скажем, вы хотите обработать много файлов как можно быстрее, где время обработки > время чтения файла.

  • Будет ли чтение нескольких файлов с использованием пула потоков увеличивать пропускную способность? или это просто вызывает больше конфликтов на диске?
  • Если пул потоков помогает, что определяет, сколько потоков необходимо для достижения максимума? это можно рассчитать на основе целевой системы?
  • Будет ли для одного ядра асинхронное чтение и обработка цикла через потоки быстрее, чем синхронное выполнение? Я предполагаю, что, поскольку задержка диска настолько высока, она будет. Но, возможно, если чтение файла намного меньше, чем время обработки, лучше позволить шагу обработки завершиться непрерывно без переключений контекста.

Кроме того, есть ли у вас какие-либо другие советы по увеличению пропускной способности диска?


  • любые другие советы по максимизации пропускной способности диска? Купите более быстрые диски и навсегда решите проблему, не беспокоясь об ошибках в ваших алгоритмах обработки, не тратя время и деньги на написание кода и не поддерживая все это. код в будущем. 07.03.2019
  • Это зависит от многих факторов. ОС, доступные процессоры, доступная память, производительность диска и так далее. Когда файлы маленькие ‹ 1 МБ и их всего несколько сотен, возможно, чтение их всех в память, а затем их обработка может быть быстрее, чем чтение, прецессия, чтение и так далее. Но я считаю, что вы должны тестировать и профилировать вещи самостоятельно. 07.03.2019
  • @AndrewHenle Всегда полезно помнить об этом. Тем не менее, если программное обеспечение предназначено для работы на множестве различных конфигураций оборудования/ОС, таких как фреймворк, вы все равно захотите использовать некоторые программные методы. 15.03.2019
  • @ user743414 Несмотря на множество возможных конфигураций, я подозреваю, что внутренние механизмы чтения данных с диска реализованы практически одинаково для различных материнских плат, процессоров, оперативной памяти и т. д. Я надеялся, что кто-то, у кого больше знаний о внутренних компонентах, может описать общие принципы, без необходимости проводить бенчмаркинг на множестве буровых установок. 15.03.2019

Ответы:


1

Я провел сравнительный анализ, чтобы выработать некоторые общие рекомендации. Я тестировал около ~ 500 000 небольших (~ 14 КБ) файлов. Я думаю, что результаты должны быть одинаковыми для файлов среднего размера; но для больших файлов я подозреваю, что конкуренция за диск становится более значительной. Было бы полезно, если бы кто-то с более глубоким знанием внутреннего устройства ОС / оборудования мог дополнить этот ответ более конкретными объяснениями того, почему некоторые вещи работают быстрее, чем другие.

Я тестировал компьютер с 16 виртуальными ядрами (8 физическими) с двухканальной оперативной памятью и ядром Linux 4.18.

Увеличивает ли количество потоков скорость чтения?

Ответ положительный. Я думаю, что это может быть связано либо с 1) аппаратным ограничением пропускной способности для однопоточных приложений, либо с 2) очередью запросов к диску ОС лучше используется, когда многие потоки делают запросы. Наилучшая производительность достигается при virtual_cores*2 потоках. После этого пропускная способность медленно снижается, возможно, из-за увеличения конкуренции за диск. Если страницы кэшируются в оперативной памяти, то лучше иметь пул потоков размером virtual_cores. Однако, если ‹ 50% страниц кэшируются (что, я думаю, является более распространенным случаем), то virtual_cores*2 подойдет.

Я думаю, что причина, по которой virtual_cores*2 лучше, чем просто virtual_cores, заключается в том, что чтение файла также включает некоторую задержку, не связанную с диском, такую ​​как системные вызовы, декодирование и т. д. Так что, возможно, процессор может более эффективно чередовать потоки: пока один ожидает на диске , второй может выполнять операции чтения файлов, не связанные с диском. (Может ли это быть связано с тем, что оперативная память двухканальная?)

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

пропускная способность чтения и количество потоков

Существует возможность использовать асинхронный дисковый ввод-вывод вместо пула потоков. Однако, судя по моим чтениям, пока нет переносимого способа сделать это (см. эту ветку Reddit). Кроме того, libuv, который поддерживает NodeJS, использует пул потоков для обработки своего файла. ИО.

Баланс между чтением и обработкой

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

prop = read_time/process_time
if prop > 1:
    # double virtual core count gives fastest reads, as per tests above
    read_threads = virtual_cores*2
    process_threads = ceil(read_threads/(2*prop))
else:
    process_threads = virtual_cores
    # double read thread pool so CPU can interleave better, as mentioned above
    read_threads = 2*ceil(process_threads*prop)

Например: чтение = 2 с, обработка = 10 с; поэтому имейте 2 потока чтения для каждых 5 потоков обработки

В моих тестах есть только около 1-1,5% потери производительности из-за наличия дополнительных потоков чтения. В моих тестах для prop, близкого к нулю, 1 чтение + 16 потоков обработки имели почти такую ​​же пропускную способность, как 32 чтения + 16 потоков обработки. Современные потоки должны быть довольно легковесными, а потоки чтения в любом случае должны находиться в спящем режиме, если файлы не потребляются достаточно быстро. (То же самое должно быть верно для потоков процесса, когда prop очень велико)

С другой стороны, слишком мало тем для чтения оказывает гораздо более значительное влияние (мой третий исходный вопрос). Например, для очень большого prop 1 чтение + 16 потоков обработки было на 36% медленнее, чем 1 чтение + 15 потоков обработки. Поскольку потоки обработки занимают все ядра тестового компьютера, поток чтения имеет слишком большую конкуренцию за ЦП и в 36% случаев не может поставить в очередь следующий файл для обработки. Итак, я рекомендую ошибиться в пользу слишком большого количества прочитанных тем. Удвоение размера пула потоков чтения, как в моей формуле выше, должно достичь этого.

Примечание. Вы можете ограничить ресурсы ЦП, потребляемые вашим приложением, задав virtual_cores меньший процент доступных ядер. Вы также можете отказаться от удвоения, поскольку конкуренция за ЦП может быть менее серьезной проблемой, когда есть запасное ядро ​​или больше, которое не выполняет более интенсивные потоки обработки.

Сводка

Основываясь на результатах моего теста, использование пула потоков с virtual_cores*2 потоками чтения файлов + virtual_cores потоков обработки файлов даст вам хорошую производительность для различных сценариев синхронизации. Эта конфигурация должна дать вам примерно 2% от максимальной пропускной способности, не тратя много времени на бенчмаркинг.

15.03.2019
  • Еще одна вещь, которую следует упомянуть, это то, что в наши дни твердотельные накопители часто рекламируют свою производительность случайного чтения с точки зрения глубины очереди, например. QD16 — это производительность чтения, если 16 потоков запрашивают 4 КБ данных. Вы можете использовать это, чтобы определить, какая глубина очереди (потоки асинхронного чтения с диска) будет оптимальной. 22.06.2021
  • Новые материалы

    Коллекции публикаций по глубокому обучению
    Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

    Представляем: Pepita
    Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

    Советы по коду Laravel #2
    1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

    Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
    Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

    3 способа решить квадратное уравнение (3-й мой любимый) -
    1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

    Создание VR-миров с A-Frame
    Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

    Демистификация рекурсии
    КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..