LINUX.ORG.RU

Qt и потоки

 ,


0

1

предИстория... если интересно:
писал я расчетные програмки в матлабе и не знал проблем...
матлаб распаралеливал и контролировал ресурсы сам...
(около 100 однообразных расчетов с разным параметром Х)... половину дня уходило на это...

решил я испытать с++... и! на один расчет в 10 раз меньше времени затрат... (без распаралеливания)...

далее GUI и Qt... и потоки... (наверное картинка была бы уместнее) для GUI поток уровня 0... далее кнопки которые создают потоки уровня 1.
1-я Одиночный расчет (с параметром X=1) в один поток уровня 1 (<10 сек).
2-я многопоточный расчет (с параметром Х от 1 до n) в поток уровня 1. в последнем потоке я создаю n потоков (одновременно) с разным параметром Х...

и тут появляются проблемы... CPU (4 ядра 1.7 ГГц) все на 100%... на ~1 минуту (если до 20 потоков [расчетов])...
но это было пол беды...
далее запустил расчеты на ~100 потоков... и понеслось... на 5 минут проц 100% (98 на саму програму 2 на остальное)... и в конце началось: Memory used: 99% (4 Gb); Swap: 99% (4 Gb)...
и в конце: The program has unexpectedly finished.

так вот собственно вопрос... можно ли как то задать проге кушать ~60% свободной «нагрузки» на проц (както задать низкий приоритет?)... или создавать оптимальное количество потоков и туда попорядку бросать расчеты? или... или...
+ не пойму почему забило всю оперативку и свап... в конце...


  • Без кода сказать что-то конкретное сложно
  • На 4 ядра больше пяти потоков смысла не имеют
  • Чтобы контролировать нагрузку нужно просто использовать таймер, чтобы часть времени поток спал.
CrossFire ★★★★★
()
Последнее исправление: CrossFire (всего исправлений: 1)
Ответ на: комментарий от CrossFire

я гуглил на счет таймера... и не сильно понял зачем программе спать... попробую тогда об этот методе почитать подробнее...
з.ы. от таймера отказался до происшествия с переполнением оперативки...
а код как можно то показать? сам алгоритм или весь код? + где... + может кто подскажет где можно задавать такие глупые вопросы знающим программистам не создавая целую тему?

st3n
() автор топика

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

This. Создавай по количеству ядер, которые ты хочешь нагрузить.

Chaser_Andrey ★★★★★
()
Ответ на: комментарий от st3n

не сильно понял зачем программе спать

В таком случае процессор не нагружается.

а код как можно то показать? сам алгоритм или весь код?

Желательно выкладывать минимально работающий пример того, что хотите сделать. Выкладывать можно как непосредственно в сообщении, обрамляя тегами [code], так и просто давая ссылку на фрагмент размещенный на http://pastebin.com/.

может кто подскажет где можно задавать такие глупые вопросы знающим программистам не создавая целую тему?

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

CrossFire ★★★★★
()

Тут уже подсказали основную идею: если есть N вычислительных задач, которые нагружают CPU, то нет смысла запускать их одновременно все. Создается K рабочих потоков (где K либо равно количеству вычислительных ядер, либо на единицу меньше /чтобы обеспечить системе какую-то отзывчивость/, либо на единицу больше /чтобы утилизировать CPU, когда какой-то поток уходит в I/O операцию или ждет чего-то/). А вычислительные задачи распределяются между этими рабочими потоками.

Готовых инструментов для этих целей довольно много. Начать можно отсюда, далее по ссылкам. Из того, что недавно еще появилось можно глянуть HPX.

eao197 ★★★★★
()
Последнее исправление: eao197 (всего исправлений: 1)
Ответ на: комментарий от Rubbiroid

я читал что Concurrent не контролируемый... во время процесса... а я хочу добавить «паузу» во время расчетов... + поставить count для отображения хода процесса.

st3n
() автор топика

ок. спасибо за информацию. пока ее достаточно для подальшего «улучшения»... но всеравно вопрос... если создам 4-5 потока... и буду туда бросать все попорядку... то оптимальнее делать паузы между каждым расчетом... чем вбрасывать их (паузы) в сам расчет... 1. если один расчет занимет ~10 секунд, то паузы в 1 секунду между ними будет достаточно?

2. если без перерывов буду бросать в 4-5 потоков все расчеты попорядку... это не равнозначно конкурирующим 50-и потокам которые распределяются самой системой?

3. как указать оптимальное время таймеру если планируется использовать прогу на разных компах... з.ы. если вопросы глупые... после «прочтения» поставлю их по другому :)

st3n
() автор топика

последнем потоке я создаю n потоков (одновременно) с разным параметром Х...

Чудила, познай OpenMP. Как раз для вычилительных задач, простое распараллеливание, познается за 10-15 минут. А свои поточные велосипеды оставь кому-то другому.

Pavval ★★★★★
()
Ответ на: комментарий от Pavval

спасибо...
OpenMP не по мне... (равносильно matlab).
останусь я пока при своих Thread и Worker...

st3n
() автор топика
Ответ на: комментарий от st3n

ээээ... все там есть. Читай доки. Ты получаешь QFuture ш дальше уже можешь и паузу ставить и отменять или завернуть в QFutureWatcher и получать сигналы с прогрессом.

Rubbiroid
()
Ответ на: комментарий от st3n

1. если один расчет занимет ~10 секунд, то паузы в 1 секунду между ними будет достаточно?

В этом смысла нету, будет то же самое, только ядро будет нагружено 100% 10 секунд и на 0% (это ложь, но пофиг) в течение секунды, разгружать CPU надо на гораздо более коротких промежутках, скажем вставлять usleep после каждого вычислительного цикла внутри задачи, даже короткий usleep скорее всего заставить scheduler отдать ядро другой задаче на какое то (возможно отличное от аргумента в большую сторону) время, таким образом нагрузка на ядро будет ниже.

elijah_sd
()
Ответ на: комментарий от st3n

если без перерывов буду бросать в 4-5 потоков все расчеты попорядку... это не равнозначно конкурирующим 50-и потокам которые распределяются самой системой?

Нет, переключение контекста — штука дорогая.

OpenMP не по мне... (равносильно matlab)

В чем равносильно? Что в программировании значит «не по мне»? Попробовать все же стоит, да

CrossFire ★★★★★
()
Последнее исправление: CrossFire (всего исправлений: 1)
Ответ на: комментарий от I-Love-Microsoft

А если blocking API с десяток экземпляров?

Не очень понимаю о чем идет речь, где можно про это почитать?

CrossFire ★★★★★
()
Ответ на: комментарий от CrossFire

я после испытаний и написал...
+ почему то с

#pragma
из 100 циклических Х.txt (Х от 1 до 100) файлов не удаляет до 10 файлов... не постоянно, но бывает пропускает...
file.close(); file.remove();
не по мне... если кратко: это совокупность методов и алгоритмов... даже в элементарном
#pragma omp parallel for

у каждого свое представление как код должен быть организован и для каких нужд... не так ли? не зря же существует куча программ... даже для однотипных задач...

st3n
() автор топика
Ответ на: комментарий от Pavval

у всех...
не все же сказали что лучше всего выдающийся OpenMP... или Thread или Concurrent...
я сам незнаю пока что лучше... поэтому и перебираю...

st3n
() автор топика
Ответ на: комментарий от st3n

omp parallel for самое простое решение, при этом в 99% процентах подходящее для конкретных вычислительных задач. При этом нету гемора с распараллеливанием, т.к. это все уже эффективно реализовали разработчики компилятора. Что тебе еще нужно? В этом треде тебе в основном отвечают то, что ты спросил. А спрашивал ты про Qt.

Pavval ★★★★★
()
Ответ на: комментарий от Pavval

спасибо за информацию и советы о omp parallel for...
возможно, поиграюсь с остальным, и вернусь к нему...
я хотел и хочу... 1. быстродействие. 2. кросплатформенность (универсальность)...
так как не у всех был, есть матлаб...
а скомпилированое с матлаб в ехе... было не полноценной программой...
уверен что еще будут проблемы и с кросплатформенностью...

st3n
() автор топика
Ответ на: комментарий от Pavval

Такое ощущение, что здесь «смешались в кучу кони, люди...» У ТС, по-видимому, сразу несколько целей. Ему хочется и GUI-оболочку иметь, в которой параметры ввел, кнопочку нажал и где-то в другом потоке пошел расчет. А потом, когда расчет закончился, чтобы результат опять в GUI-отобразился. При этом ТС хочет иметь возможность запустить из GUI несколько расчетов параллельно.

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

Поэтому, по-хорошему, ему нужно изучать и инструменты вроде IBB/HPX, и инструменты вроде OpenMP.

Но для начала ему не мешало бы уяснить, что такое parallel computing, зачем нужен и с чем едят. Может тогда не будет перлов про использование таймеров и пр. лабуды.

eao197 ★★★★★
()
Ответ на: комментарий от eao197

по-видимому, сразу несколько целей

да. и я их огласил с самого начала...
и задача" найти золотую срединку во всём, или стремится к этому...

и что в этом есть необходимость

есть, так как уменьшается затраченое время...
для меня (как для «не программиста») parallel computing это распаралеливание однотипных вычислений, что приводит к ускорению процесса... и этого, в принципе, достаточно.
з.ы. использование таймеров... я не осилил, точнее не старался, а пришел к выводу что проще использовать 3 потока для 4-х ядерного проца (n-1)... а еще проще использовать инструменты вроде OpenMP... а еще же можно и консольно...

как по мне полноценное углубленное изучение разных инструментов и библиотек и языков не является необходимостью для написания таких простых задач, даже если это выглядит для специалиста как:
<«смешались в кучу кони, люди...»

st3n
() автор топика
Ответ на: комментарий от anonymous

по этому он такой медленный?

st3n
() автор топика

всем спасибо!
я нашел для себя ответы и много советов. будем чтото делать дальше...

st3n
() автор топика
Ответ на: комментарий от st3n

для меня (как для «не программиста») parallel computing это распаралеливание однотипных вычислений, что приводит к ускорению процесса... и этого, в принципе, достаточно.

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

1. Разобраться с точками распараллеливания ваших вычислительных алгоритмов. Тут вы, как специалист сами должны лучше всех понимать что к чему.

2. Разобраться с тем, какими ресурсами вы располагаете (ядра CPU, память, дополнительные узлы кластера и т.д.) и как лучше распределить эти ресурсы между вашими вычислительными задачами.

Ну и со второй поляной, как бы вы себя не позиционировали как «не программиста», вам придется разбираться и становится специалистом. И для начала вам нужно самому себе ответить, что вам нужно:

- консольное приложение, заточенное под одну вычислительную задачу, которому на вход N параметров, на выходе результаты расчетов (тогда дальше OpenMP можно не смотреть);

- GUI приложение, заточенное под одну вычислительную задачу, в котором задается N параметров и отображаются результаты расчетов (тогда Qt для GUI, OpenMP для расчетов);

- GUI приложение, являющееся менеджером нескольких вычислительных задач. Т.е. GUI-приложение из которого можно одновременно запустить несколько разных вычислительных задач параллельно. Тогда просто Qt и просто OpenMP будет мало. Т.к. если вы запустите N независимых задач, в каждой из которых OpenMP в полный рост, а в наличии всего K вычислительных ядер, то серьезные тормоза вам обеспечены. Т.к. ресурсов мало, а конкуренция за них высокая.

PS. Кстати вопрос: а почему такая крайность из MathLab в C++, а не, скажем, в Matematica?

eao197 ★★★★★
()
Последнее исправление: eao197 (всего исправлений: 1)
Ответ на: комментарий от eao197

1. еще в матлабе было сделано...
2. располагаю: a) 4-х ядерный 1.7 ГГЦ бук 4 Гб RAM; (+ подобные ему, пишу для такой конфигурации) [это для повседневной работы]
б) 8-ми ядерный 2.5 ГГц 16 Гб RAM [по необходимсти]
в) до 8-ми ядер 24 х Opteron 6176 2.3 ГГц 64 Гб RAM [по очень большой необходимости]
вариант в) я пока в счет не беру для этой задачи...
о второй поляне:
как по мне, консольные программы для: 1. долгих расчетов... очень долгих... 2. не нуждающие в подальшей обработке и, или быстрой визуализации результатов...
почему я вообще перешел на GUI:
олд скул... сидит в консольной программе (к этой никакого отношения)... пишет инфу в текстовый файл на протяжении минуты, которая за пару минут рожает более 30 файлов. далее это все бросается в ориджин... «линейкой на экране» меряется растояние... итак по кругу по раз 5... пока глаз(мозок) не будет удовлетворен... и это типичные задачи...
ПОЭТОМУ GUI...
загрузил файл в прогу. поменял значения уже в ней. нажал кнопку. 30 кривых на графике с последующей возможностью програмно тыкать на них и получать дополнительную инфу... + заключительный (или любой) результат сохранять в текстовом или другом виде. Вы согласны со мной о пользе(преимуществе) GUI в даном случае?
если смотреть без изврата... на мою задачу... то GUI + OpenMP (при условии - GUI не тормозит) достаточно будет. но мне хочется чтото среднее между однотипной задачей и менеджером. поэтому GUI(поток 1), с одним параметром (поток 2 (thread)), с разным значением параметра (поток 3, и в нем создаем распаралеливание с помощью OpenMP). точка
почему с++?
1. почему матлаб а не математика: еще в универе было замечено что для аналитических исчислений лучше подходит Matematica, а для численных методов матлаб (+ вспоминаются слова профа: только в единичных случаях уравнение шрёдингера можно решить аналитически)... + матлаб работает (оперирует) напрямую с матрицами, а это было в тот момент важно. + матлаб совместим с comsolом... + можно еще чего вспомнить о преимуществах(в моем случае) матлаба над математикой...
2. без распаралеливания в консольном варианте... я скопировал код с матлабовского м-файла в срр-файл... поменял разметку для for... и изменял инициализацию переменных... + что самое трудное было... так это отвыкнуть, что функция не может вернуть более одной переменной...
3. не вижу большой разницы в синтаксисе... (без придирки до сигнал-слот и метод-класс) вот только с распаралеливанием столкнулся...

st3n
() автор топика
Ответ на: комментарий от st3n

2. располагаю

Речь не только об инвентаризации оборудования. Но еще и о том, сколько в вашем алгоритме операций, какой у них характер и как лучше их разложить по имеющимся ядрам.

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

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

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

Самое простое решение в данном случае выглядит так:

- создаете (K-1) рабочий поток для вычислений (где K — это количество ядер);

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

eao197 ★★★★★
()
Ответ на: комментарий от anonymous

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

st3n
() автор топика
Ответ на: комментарий от eao197

все правильно. вот так я и хочу :)
если забыть пока о ГУИ...
смысл такой:
1. читаем файл (до 1 кб) добавляем к нему параметр Х. (получаем масив данных А)
2. for {обработка части масива А} получаем масив Б
(~45% времени) 3. for {обработка масива Б+А} получаем масив В
(~10% времени) 4. for {обработка масива В+А} получаем масив Г
(~45% времени) 5. пишем файлы с масива Г;
это не распаралеливается... (может удивите меня?)
а на паралельное исчисление 1-5 с разным параметром Х... с 6-м шагом: объединение всех файлов в: (3 бмп(по 1 мб)[большие матрицы приятнее сохранять так] и 3 текстовых (до 1кб) [вектора]).
почему гуи. 1. загружаем файл. меняем параметры(если нужно) и сразу выводим данные с масива А на график... и для 2-5 также можно... изменяем данные с возможным контролем после каждого пункта.
если все устраивает... запускаем паралельное исчисление...
надеюсь, доходчиво объяснил...

st3n
() автор топика
Ответ на: комментарий от st3n

надеюсь, доходчиво объяснил...

Более менее, но вот форматировать нормально свои сообщения вам бы очень не помешало.

Кстати, я так и не понял. Вот, например, шаг 2, где из A получается Б. Внутри этого шага распараллеливание же возможно?

eao197 ★★★★★
()
Ответ на: комментарий от eao197

к сожалению нет. но возможно (О_о)... если... и это если мне не подходит...
это классический shooting method.
методом перебора(увеличения) Х (начиная с 0, например). ищем когда Y=f(X) равна 0 или изменяет знак. и так пока не будет найдено определенное количество этих нулевых точек...
на всякий пожарный: eigenvalues i eigenvectors здесь не применим.
у меня в коде while для шага 2 написано... но не сильно хотел в подробности влезать... можно это while заменить на for{} записать вектор Y с более 10000 double. потом найти нули этой функции, если не достает... то еще увеличивать Х... но это + куча кода + маловероятное удобное распаралеливание...
хотя на досуге досуга испытаю (спасибо за идею!)

+ тогда вопрос... смысла же нет распаралеливать, когда очень много for с малым количеством операций в нём. пример: for (int i=0; i<1e6; i++) Y [ i ] = i;

st3n
() автор топика
Ответ на: комментарий от st3n

смысла же нет распаралеливать, когда очень много for с малым количеством операций в нём. пример: for (int i=0; i<1e6; i++) Y [ i ] = i;

Если при таких операциях изменения отдельных ячеек никак не связано со значениями в других ячейках (т.е. модификации независимы друг от друга), то имеет смысл. Т.е. если у нас 1M ячеек, мы можем модифицировать их в четыре потока: [0..(250K-1)],[250K..(500K-1)],[500K..(750K-1)],[750K..(1M-1)] (потоков может быть столько, сколько вычислительных ядер). Насколько я помню, OpenMP как раз имеет готовые прагмы для таких вещей. Да и библиотеки вроде IBB или HPX должны предоставлять возможности для таких операций.

eao197 ★★★★★
()
Ответ на: комментарий от eao197

ok. спасибо. будем испытывать.
потом, как-то, выложу на всеобщее осуждение... :)

st3n
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.