Эффективный способ сохранения данных на диск при выполнении ресурсоемкой задачи.

StackOverflow https://stackoverflow.com/questions/1014113

Вопрос

Я работаю над научным программным обеспечением, которое очень интенсивно использует процессор (его привязка к процессору), но ему необходимо довольно часто записывать данные на диск (привязка ввода-вывода).

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

Я ищу «лучшую практику» для этого, и скорость — это то, что меня волнует больше всего (это могут быть очень длинные симуляции).

Спасибо ~ Алекс

Первые мысли:

наличие отдельного процесса выполняет фактическую запись на диск, поэтому симуляция состоит из двух процессов:один привязан к ЦП (моделирование), а другой — к вводу-выводу (запись файла).Это звучит сложно.

Возможно, труба/буфер?Я новичок в этом, так что, возможно, это может быть возможным решением.

Это было полезно?

Решение

Если вы реализуете OpenMP в своей программе, лучше использовать #pragma omp сингл или #прагма омп мастер из параллельного раздела для сохранения в файл.Эти прагмы позволяют только одному потоку выполнять что-либо.Итак, ваш код может выглядеть следующим образом:

#pragma omp parallel
{
    // Calculating the first part
    Calculate();

    // Using barrier to wait all threads
    #pragma omp barrier

    #pragma omp master
    SaveFirstPartOfResults();

    // Calculate the second part
    Calculate2();

    #pragma omp barrier

    #pragma omp master
    SaveSecondPart();

    Calculate3();

    // ... and so on
}

Здесь группа потоков будет выполнять вычисления, но только один поток сохранит результаты на диск.

Это похоже на программный конвейер.Я предлагаю вам рассмотреть шаблон tbb::pipeline из библиотеки Intel Threading Building Blocks.Я могу отослать вас к руководству по программным конвейерам по адресу http://cache-www.intel.com/cd/00/00/30/11/301132_301132.pdf#page=25.Пожалуйста, прочтите пункт 4.2.Они решили проблему:один поток для чтения с диска, второй для обработки прочитанных строк, третий для сохранения на диск.

Другие советы

Я бы сказал, что лучшим способом было бы создать другой поток для сохранения данных, а не совершенно новый процесс;с новым процессом вы сталкиваетесь с проблемой передачи сохраняемых данных через границу процесса, что создает новый набор трудностей.

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

Проблема в том, что на самом деле ваш цикл моделирования не завершен, пока не будут выданы результаты.

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

Первое решение было бы лучше, если бы цикл обработки моделирования менялся (иногда меньше, чем время записи, иногда дольше), потому что в среднем записи могут идти в ногу с симуляцией.

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

Поскольку вы привязаны к процессору и вводу-выводу:Дайте угадаю:Памяти еще достаточно, верно?

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

По самому написанию:Рассмотрите возможность использования ввода-вывода с отображением в памяти.Прошло много времени с тех пор, как я проводил тесты, но в прошлый раз это было значительно быстрее.

Также вы всегда можете торговать процессорами и процессорами.ИО немного.Я думаю, вы сейчас записываете данные в виде необработанных несжатых данных, верно?Вы можете получить некоторую производительность ввода-вывода, если используете простую схему сжатия для уменьшения объема записываемых данных.С библиотекой ZLIB довольно легко работать, и она очень быстро сжимает данные на самом низком уровне сжатия.Это зависит от характера ваших данных, но если в них много избыточности, даже очень грубый алгоритм сжатия может устранить проблему, связанную с вводом-выводом.

Один поток постоянно выполняет шаг трудоемкого процесса, а затем добавляет частичный результат в очередь частичных результатов.Другой поток постоянно удаляет частичные результаты из очереди и записывает их на диск.Обязательно синхронизируйте доступ к очереди.Очередь — это структура данных в виде списка, в которой вы можете добавлять элементы в конец и удалять элементы в начале.

Сделайте так, чтобы в вашем приложении было два потоки, один для процессора и один для жесткого диска.

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

Таким образом, ЦП просто избавляется от данных и позволяет кому-то другому их обработать, а жесткий диск просто терпеливо ждет любых данных в своей очереди.

С точки зрения реализации вы могли бы реализовать очередь как объект с общей памятью, но я думаю, что канал — это именно то, что вам нужно.Процессор просто записывает в канал, когда это необходимо.Что касается жесткого диска, вы просто прочитаете канал и, как только получите действительные данные, продолжите работу оттуда.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top