Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 29.04.2017, 06:28   #1
Haric_110
Форумчанин
 
Регистрация: 03.03.2013
Сообщений: 102
Вопрос Операции в больших циклах

Здравствуйте, уважаемые программисты!
Всем известно, что когда в программе присутствует цикл с огромным количеством повторений, его тело должно быть идеальным (настолько же идеальным, что и тело женщины, желающей стать моделью популярного мужского журнала), и в то же время, оно должно решать указанную задачу...
На моём пути такая проблема возникла при моделировании системы с очень большим числом частиц и интегрировании методом Монте-Карло. Число итераций цикла может исчисляться квинтиллионами... самой тяжёлой операцией цикла является генерация случайных чисел. Я использую "Вихрь Мерсенна" из стандартной библиотеки.
Первый вопрос: как найти компромисс между качеством случайных чисел и производительностью программы?
Далее... так как требуется производить огромное количество вычислений, в любом случае, программа будет работать долго. Я хочу иметь возможность приостановить её, вывести промежуточный результат, записать его и потом продолжить вычисления.
Второй вопрос: как отслеживать считывание с клавиатуры с минимальным ущербом производительности? _kbhit тут определённо не проходит...

Жду совета, надеюсь на Вашу помощь!
Haric_110 вне форума Ответить с цитированием
Старый 29.04.2017, 06:34   #2
Haric_110
Форумчанин
 
Регистрация: 03.03.2013
Сообщений: 102
По умолчанию

Вообще, я хотел создать тему в разделе "Общие вопросы по с++"... можно переместить её? или продублировать... Давно не заходил на форум, как-будто поменялось всё)

Последний раз редактировалось Haric_110; 29.04.2017 в 06:46.
Haric_110 вне форума Ответить с цитированием
Старый 29.04.2017, 15:30   #3
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

Цитата:
Сообщение от Haric_110 Посмотреть сообщение
тему в разделе "Общие вопросы по с++"... можно переместить её?
перенёс
Serge_Bliznykov вне форума Ответить с цитированием
Старый 29.04.2017, 15:37   #4
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,330
По умолчанию

Цитата:
Сообщение от Haric_110 Посмотреть сообщение
как найти компромисс между качеством случайных чисел и производительностью программы
Никак, просто надо решить, что для вас важнее. Ну или придумать быстрый генератор и получить нобелевку.
Цитата:
Сообщение от Haric_110 Посмотреть сообщение
как отслеживать считывание с клавиатуры с минимальным ущербом производительности
Это зависит от платформы, в языке стандартного способа нет. Если вам надо просто останавливать вычисление, то запустите два потока и пусть считающий поток проверяет флаг остановки а второй поток обрабатывает сигналы клавиатуры и устанавливает этот флаг, если нужно.
waleri вне форума Ответить с цитированием
Старый 29.04.2017, 15:59   #5
Pavia
Лис
Старожил
 
Аватар для Pavia
 
Регистрация: 18.09.2015
Сообщений: 2,409
По умолчанию

Цитата:
Второй вопрос: как отслеживать считывание с клавиатуры с минимальным ущербом производительности? _kbhit тут определённо не проходит...
Достаточно разделить вашу задачу на вложенные циклы.
Код:
count=10000000000000;
count2=1000;
count1= count / count2;
for(int i; 0<count1 || OutFlag; i++)
{
for(int i; 0<count1; i++)
{
.. // ваши расчёты
}
OutFlag=KeyTest();
}
В таком случае KeyTest составит менее 0,1% от суммарной производительности.
Если надо меньше увеличиваете count2.

Цитата:
Первый вопрос: как найти компромисс между качеством случайных чисел и производительностью программы?
Доказать что качество стандартного генератора не хватает. И сделать вывод что длину основного цикла надо снизить.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
У дзен программиста программа делает то что он хотел, а не то что он написал .
Pavia вне форума Ответить с цитированием
Старый 29.04.2017, 18:22   #6
Haric_110
Форумчанин
 
Регистрация: 03.03.2013
Сообщений: 102
По умолчанию

Цитата:
Сообщение от Serge_Bliznykov Посмотреть сообщение
перенёс
спасибо!
Haric_110 вне форума Ответить с цитированием
Старый 30.04.2017, 01:46   #7
Haric_110
Форумчанин
 
Регистрация: 03.03.2013
Сообщений: 102
По умолчанию

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

Последний раз редактировалось Haric_110; 30.04.2017 в 01:49.
Haric_110 вне форума Ответить с цитированием
Старый 30.04.2017, 01:52   #8
Haric_110
Форумчанин
 
Регистрация: 03.03.2013
Сообщений: 102
По умолчанию

Цитата:
Сообщение от waleri Посмотреть сообщение
запустите два потока и пусть считающий поток проверяет флаг остановки а второй поток обрабатывает сигналы клавиатуры и устанавливает этот флаг, если нужно.
хм, я раньше не работал с параллельными потоками... можно узнать по-подробнее основные моменты?
Haric_110 вне форума Ответить с цитированием
Старый 30.04.2017, 02:18   #9
alexzk
Форумчанин
 
Регистрация: 12.04.2017
Сообщений: 889
По умолчанию

Цитата:
Сообщение от Haric_110 Посмотреть сообщение
хм, я раньше не работал с параллельными потоками... можно узнать по-подробнее основные моменты?
Для С++11 рекомендовано std::async (там заморочка с запуском, по умолчанию, нового потоко может и небыть). Если он почему-то не подходит std::thread.

На g++ можно попробовать распараллелить стандартные алгоритмы через openmp
https://gcc.gnu.org/onlinedocs/libst...llel_mode.html
Для вычислений мне это представляется отпимальным.

Там не совсем очевидно, но для обработки массива данных и получения такого же размера, но других данных идеален std::transfer.
Т.е.
1. Пишите программу с использованием стандартных алгоритмов, с прицелом на параллельность (т.е. нельзя самостоятельно посчитаное записывать в массив результатов скажем, или вести индекс элемента).
2. Подключаете параллельность, вот примерчик:
https://github.com/alexzk1/astroed/b...s/palgorithm.h

пользоватся типа

ALG_NS::sort(a.b);


Вот пример включения openmp в qmake

Код:
openmp {
DEFINES *= USING_OPENMP
QMAKE_CXXFLAGS *= -fopenmp
QMAKE_LFLAGS   *= -fopenmp
#uncomment to try global parallels
#DEFINES *= _GLIBCXX_PARALLEL
}
В Целом прога может быть такая:
1. Запускаете цикл расчетов async/thread (https://github.com/alexzk1/astroed/b...tils/runners.h - опять примерчик, цикл работает, пока на него существует указатель тут)
2, В цикле (1) запускаете параллельные расчеты через опенмп.
3. Основная прога ждет указаний с клавиатуры.

Так же вам прийдется освоить синронизации, в частности, для передачи с клавиаутры что-то в поток (например коэф. double) стоит использовать std::atomic<double>, еще тема почитать std::mutex, std::lock_guard.
Потому что, такие задачи физически параллельны на разных ядрах и вы должны гарантировать отсутсвие столкновений при доступе в 1 участок памяти. Нельзя, скажем, обоим сразу писать, тогда не ясно, какой должен быть результат записи. +Кеши, часть памяти может быть в кеше процессора, тогда 2 потока будут по факту работать с двумя разными копиями данных (в простейшем случае volatile слово подавляет кеширование).

Использование openmp хорошо тем, что автоматически будет работать на всех доступных процессорах (а с доп.трюками, можно расчеты на GPU сбросить) без переделки кода в целом.

Последний раз редактировалось alexzk; 30.04.2017 в 02:46.
alexzk вне форума Ответить с цитированием
Старый 30.04.2017, 02:59   #10
Haric_110
Форумчанин
 
Регистрация: 03.03.2013
Сообщений: 102
По умолчанию

alexzk, благодарю, вещь полезная будем изучать)
О том, как применить конкретно в моём случае: как я понимаю, принцип состоит в том, чтобы разделить задачу между логическими процессорами, типа: 2 или 3 из 4-х заняты основными вычислениями а первом потоке, а остальные 2 или 1 проверяют чтение с клавиатуры, таким образом, процессор в результате загружается сильнее, производительность не страдает...

Не, я обязательно освоюсь в этой теме... ведь я планирую в перспективе увеличить число вычислений... я слышал, в моделировании из первых принципов всё только и стоит на параллельных вычислениях
Haric_110 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
WriteFile в циклах _PROGRAMM_ Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 3 11.02.2012 23:00
Нужно на циклах реализовать. renat1501 Помощь студентам 5 18.09.2011 21:28
RANDOM в циклах Stakhoff Общие вопросы C/C++ 5 05.04.2011 12:52
глюк в циклах Rio309 Общие вопросы Delphi 4 05.10.2009 15:44
вопрос о циклах alexsamurai Microsoft Office Excel 9 10.01.2009 13:25