Russian Qt Forum
Апрель 18, 2024, 08:13 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2 3   Вниз
  Печать  
Автор Тема: параллельная обработка файлов  (Прочитано 19027 раз)
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4727



Просмотр профиля WWW
« : Февраль 12, 2016, 17:45 »

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

Есть папка с n файлами. Требуется загрузить данные из каждого файла (файлы маленькие, не более 10 кб, нужных данных и того меньше), а потом провести перекрестное сравнение файлов (т.е. сравнить данные 1-го файла с 2,3,...,n и т.д.).

Сейчас у меня сделано очень банально: слот загрузки/обработки запускается через QtConcurrent::run(), а интерфейс обновляется через QMetaObject::invokeMethod(). Процессор при этом загружается на 30% (по ядрам не смотрел), а сам процесс отрабатывает крайне долго для 10к файлов. (даже для 500 файлов приходится ждать секунд 30)

Это можно как-то распараллелить и ускорить?
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4349



Просмотр профиля
« Ответ #1 : Февраль 12, 2016, 18:26 »

10 000 файлов * 10К = 100Мб, даже если таких файлов будет 100 000, то они все займут чуть больше 1Гб. Расходы на память приемлемые, поэтому не вижу причин отказываться от их загрузки в память и дальнейшем разборе уже без чтения с диска.
Поэтому, я бы разделил этот вопрос на два:
* параллельная загрузка всех файлов в память
* параллельная их обработка.
С какой начнем?
Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4727



Просмотр профиля WWW
« Ответ #2 : Февраль 12, 2016, 18:37 »

10 000 файлов * 10К = 100Мб, даже если таких файлов будет 100 000, то они все займут чуть больше 1Гб. Расходы на память приемлемые, поэтому не вижу причин отказываться от их загрузки в память и дальнейшем разборе уже без чтения с диска.
сейчас я так и делаю, только память на этих 10к вырастает до 400 МБ (это с учетом создания необходимых структур данных), но это нестрашно.
Поэтому, я бы разделил этот вопрос на два:
* параллельная загрузка всех файлов в память
* параллельная их обработка.
С какой начнем?
логично начать с первого пункта Улыбающийся
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4349



Просмотр профиля
« Ответ #3 : Февраль 12, 2016, 18:53 »

Самый простой в реализации вариант с использованием  QtConcurrent.
Посмотрите пример Image Scaling Example, только вместо скалинга картинок загружайти файлы в QByteArray. Из коробки будет прогресс, сигнал окончания и коллекция результирующих буферов.
Тоже можно сделать руками, с организацией пула рабочих потоков, очередями заданий и средствами синхронизации или использовать openmp. Улыбающийся
« Последнее редактирование: Февраль 12, 2016, 19:00 от Old » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #4 : Февраль 12, 2016, 19:08 »

сейчас я так и делаю, только память на этих 10к вырастает до 400 МБ (это с учетом создания необходимых структур данных), но это нестрашно.
А в чем заключается сравнение? По размеру файла, по содержимому, или как-то хитро? Не верится в полчаса, пусть и на одной нитке
Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4727



Просмотр профиля WWW
« Ответ #5 : Февраль 12, 2016, 20:02 »

Самый простой в реализации вариант с использованием  QtConcurrent.
Посмотрите пример Image Scaling Example, только вместо скалинга картинок загружайти файлы в QByteArray. Из коробки будет прогресс, сигнал окончания и коллекция результирующих буферов.
спасибо, попробую
сейчас я так и делаю, только память на этих 10к вырастает до 400 МБ (это с учетом создания необходимых структур данных), но это нестрашно.
А в чем заключается сравнение? По размеру файла, по содержимому, или как-то хитро? Не верится в полчаса, пусть и на одной нитке
хитро по содержимому Улыбающийся файлы — это сохранения диабло 2, задача — поиск клонированных предметов.
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4727



Просмотр профиля WWW
« Ответ #6 : Февраль 13, 2016, 00:35 »

пример посмотрел, оказывается все достаточно просто Улыбающийся

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

теперь в шаге 2 имеется QHash<QString, QList> и нужно провести сравнение каждого с каждым (списки, естественно, сравниваются поэлементно). Можно ли разрезать хэш пополам и раздать сравнение 3-м потокам, которые будут сравнивать 1 с 1, 2 с 2 и 1 с 2? Или лучше как-то по-другому?
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #7 : Февраль 13, 2016, 08:13 »

...поэтому переделывать синглтон не буду — слишком уж много возни получится.
Multi-threading - отличное лекарство от синглтон и глобальных переменных вообще  Улыбающийся

теперь в шаге 2 имеется QHash<QString, QList> и нужно провести сравнение каждого с каждым (списки, естественно, сравниваются поэлементно). Можно ли разрезать хэш пополам и раздать сравнение 3-м потокам, которые будут сравнивать 1 с 1, 2 с 2 и 1 с 2? Или лучше как-то по-другому?
Надо стремиться к равномерной загрузке ниток, поэтому напрашивается аналогия с суммой арифметической прогрессии,
1 + 100
2 + 99
3 + 98
...
Так сразу известно число задач и они примерно равны. Рез-ты сравнения лучше писать в саму задачу, обходясь без всяких блокировок
Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4727



Просмотр профиля WWW
« Ответ #8 : Февраль 13, 2016, 16:52 »

то есть хэш разрезать на n/2 частей и на каждую выделить нить, которая будет проводить 3 сравнения?
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #9 : Февраль 13, 2016, 17:15 »

то есть хэш разрезать на n/2 частей и на каждую выделить нить, которая будет проводить 3 сравнения?
Не нужно никого резать, и хеш не нужен. Есть контейнер в котором каждый эл-т соответствует файлу (данные). Теперь формируем "задачи" которые будем скармливать ниткам (число задач не зависит от числа ниток)

Первая задача будет сравнивать первый файл со всеми остальными
Вторая задача будет сравнивать второй файл со всеми последующими + предпоследний с последним
Третья - третий файл со всеми последующими + 3 последних
и.т.д

Задаче надо знать только контейнер и 2 индекса с которых начинать
Записан
poru
Самовар
**
Offline Offline

Сообщений: 103


Просмотр профиля
« Ответ #10 : Февраль 15, 2016, 12:52 »

Вспомнилась мне точно такая же история. Нужно было в строго определенное время анализировать ~40000 техпроцессов (1 тп - 1 файл). Программа была написана задолго до меня в Delphi и отрабатывала за 2,5 часа. Руководству для принятия каких-то там решений оставалось 30 минут и попросили ускорить. Переписал все в Builder 2006 и результат получал через 40 минут. Все в восторге! Но какой то гвоздь в заднице не давал покоя и в одну  из новогодних ночей переписал все на чистом "С" без шаблонов, классов, с загрузкой файлов в память и расчета смещения указателей и все на 2-х потоках. Программа обсчитала все эти файлы за полторы минуты. Я в шоке! Руководство в испуге! Попросили больше таких программ не писать) Использование привычных классов будет вас тормозить.
Записан
Bepec
Гость
« Ответ #11 : Февраль 15, 2016, 17:25 »

Ну тут уже вопрос, стоит ли овчинка выделки?
Ну и да, вопрос сколько обрабатывать будет простой цикл?

Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4727



Просмотр профиля WWW
« Ответ #12 : Февраль 15, 2016, 18:49 »

это мне вопрос? ну время указано в первом посте
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
Bepec
Гость
« Ответ #13 : Февраль 15, 2016, 19:53 »

А есть возможность скинуть минимальный проект и файлы для обработки?
Я б тогда поковырялся.
Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4727



Просмотр профиля WWW
« Ответ #14 : Февраль 15, 2016, 22:13 »

трудно будет вычленить минимальный

тема создана не для «напишите мне», а «расскажите как правильно сделать и что почитать».
то есть хэш разрезать на n/2 частей и на каждую выделить нить, которая будет проводить 3 сравнения?
Не нужно никого резать, и хеш не нужен. Есть контейнер в котором каждый эл-т соответствует файлу (данные). Теперь формируем "задачи" которые будем скармливать ниткам (число задач не зависит от числа ниток)

Первая задача будет сравнивать первый файл со всеми остальными
Вторая задача будет сравнивать второй файл со всеми последующими + предпоследний с последним
Третья - третий файл со всеми последующими + 3 последних
и.т.д

Задаче надо знать только контейнер и 2 индекса с которых начинать
вот это буду пробовать
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
Страниц: [1] 2 3   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.054 секунд. Запросов: 23.