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

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

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

Сообщений: 3260


Просмотр профиля
« Ответ #15 : Май 22, 2020, 10:45 »

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

Если что, проверка на паузу -  это атомарная переменная с relaxed memory order. Если relaxed проверка тормозит расчёты то может стоит подумать о том что расчёты вообще не должны быть в потоке?=)
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #16 : Май 22, 2020, 12:55 »

А любое добавление проверок или индикации в код расчета замедлит его в разы.
Ну как.. это типовая проблема/ошибка - переборщить с индикатором. Но если делать аккуратно, то все норм, напр
Код
C++ (Qt)
std::atomic<int>prev, cur;
const int updateStep = 100;
 
#pragma omp parallel for
for (int i = 0; i < vec.size(); ++i) {
 DoCalc(vec[i]);
 ++cur;  
 #pragma omp master    // обновляем индикатор в главной нитке через каждые 100 итераций
 {
   if (cur - prev >= updateStep) {
     UpdateIndicator(cur - prev);
     prev = cur;
   }
 }
}

Если что, проверка на паузу -  это атомарная переменная с relaxed memory order. Если relaxed проверка тормозит расчёты то может стоит подумать о том что расчёты вообще не должны быть в потоке?=)
Собсно "проверка" - да, но нужно как-то поток остановить, и футуры здесь не помогут. И вообще, Вы прямо терроризируете начинающих.  "relaxed memory order" - бог весть что можно подумать, а это всего лишь самое обычное чтение переменной Улыбающийся Ну если уж и оно тормозит...

И, кстати, как бум останавливать "по-нормальному" ? (sleep не есть хорошо). Давайте Вы на QWaitCondition,  а я на своем любимом QSemaphore
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #17 : Май 22, 2020, 13:13 »

И, кстати, как бум останавливать "по-нормальному" ? (sleep не есть хорошо). Давайте Вы на QWaitCondition,  а я на своем любимом QSemaphore

Код:
void foo(QFutureInterface<int> promise)
{
    constexpr int iterations = 10000000;

    int result = 0;
    for (int i = 0; i < iterations; ++i) {
       if ((i % 1000) == 0 && promise.isPaused()) // relatively fast
          promise.waitForResume(); // slow, locks the mutex
       result += qHash(i);
    }
    promise.setResult(result);
}

А вы продолжайте писать велосипеды с семафором=)

Да, чтобы иметь возможность запускать через промис, надо потырить вот этот файлик из QtCreator, всячески рекомендую (его переписали на вариадики, кстати) https://code.woboq.org/qt5/qt-creator/src/libs/utils/runextensions.h.html

Запускать так:
Код:
#include "runextensions.h"

auto future = Utils::runAsync(foo);
« Последнее редактирование: Май 22, 2020, 13:20 от Авварон » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #18 : Май 22, 2020, 18:45 »

Код:
void foo(QFutureInterface<int> promise)
{
    constexpr int iterations = 10000000;

    int result = 0;
    for (int i = 0; i < iterations; ++i) {
       if ((i % 1000) == 0 && promise.isPaused()) // relatively fast
          promise.waitForResume(); // slow, locks the mutex
       result += qHash(i);
    }
    promise.setResult(result);
}

А вы продолжайте писать велосипеды с семафором=)

Да, чтобы иметь возможность запускать через промис, надо потырить вот этот файлик из QtCreator, всячески рекомендую (его переписали на вариадики, кстати) https://code.woboq.org/qt5/qt-creator/src/libs/utils/runextensions.h.html

Запускать так:
Код:
#include "runextensions.h"

auto future = Utils::runAsync(foo);
Ничего не понял Улыбающийся iterations - это число задач/расчетов? Но в цикле Вы ничего не запускаете. Запуск где-то в др месте? Но в runAsync Вы подаете foo. Чему посвящен приведенный код, что он делает? Пока выглядит просто как бред собачий Улыбающийся
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #19 : Май 22, 2020, 18:56 »

Igors, перечитай код еще раз, он очень простой и все в нем нормально.
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #20 : Май 23, 2020, 07:33 »

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

И вообще, в чем "хотелка"? Иметь удобные вызовы индикатор/пауза/отмена ? Все. что ли? Если так то эти мелкие подробности легче пристроить самому (если еще они понадобятся) чем забивать голову монструозными классами с мизерным ф-ционалом. Проблемы "разпоточивания" совсем в другом. В любой системе это ведь только так предполагается что есть/имеются N задач которые могут выполняться одновременно, на самом деле выделить/создать их часто очень непросто.
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #21 : Май 23, 2020, 09:18 »

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

Странно, этот код будет понятен даже джуну...

И вообще, в чем "хотелка"? Иметь удобные вызовы индикатор/пауза/отмена ? Все. что ли? Если так то эти мелкие подробности легче пристроить самому (если еще они понадобятся) чем забивать голову монструозными классами с мизерным ф-ционалом. Проблемы "разпоточивания" совсем в другом. В любой системе это ведь только так предполагается что есть/имеются N задач которые могут выполняться одновременно, на самом деле выделить/создать их часто очень непросто.

Эта штука для того, чтобы каждый не пилил свой велосипед с незащищенным доступом к переменным, а юзал защищенные и быстрые вызовы.
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #22 : Май 23, 2020, 10:17 »

Странно, этот код будет понятен даже джуну...
Думаю что нет. Ну если конечно джун не делает вид что, мол, ему все понятно Улыбающийся. Ну в самом деле
Код:
void foo(QFutureInterface<int> promise)
{
    constexpr int iterations = 10000000;

    int result = 0;
    for (int i = 0; i < iterations; ++i) {
       if ((i % 1000) == 0 && promise.isPaused()) // relatively fast
          promise.waitForResume(); // slow, locks the mutex
       result += qHash(i);
    }
    promise.setResult(result);
}
Не вижу где сами расчеты. Ну ладно, допустим они где-то в др месте, тогда выходит foo выполняется в главной нитке и только "забирает рез-т", наверно с помощью qHash. И что он должен делать/возвращать если задача еще не посчитана или вообще стоим на паузе?

И кто/как ставит на паузу? Наверно надо эту футуру подать в расчет, а там уж вызвать ее метод (а как иначе?). Опять только догадки, лучшего нет. А Вы говорите "все ясно"

Эта штука для того, чтобы каждый не пилил свой велосипед с незащищенным доступом к переменным, а юзал защищенные и быстрые вызовы.
Какие? Пауза что нужна в году раз и которую сделать 5 минут? И ради этого тащить немалый кусок темплейтовской срани? Та ну нафиг. И, кстати, вещь совсем не новая, но документировать не спешат, видимо сами "не удовлетворены"
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #23 : Май 23, 2020, 13:21 »


И кто/как ставит на паузу? Наверно надо эту футуру подать в расчет, а там уж вызвать ее метод (а как иначе?). Опять только догадки, лучшего нет. А Вы говорите "все ясно"

В расчёт вы подаете promise. На паузу ставит футура:

Код:
#include "runextensions.h"

auto future = Utils::runAsync(foo);
future.pause();
future.resume();
future.waitForFinished();
int result = future.result();
qInfo() << result;
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #24 : Май 23, 2020, 13:23 »

Хм, не думал, что все так туго...
Код
C++ (Qt)
result += qHash(i);
- это и есть весь расчет. Ты же не думал, что тебе тут напишут код расчета зависимости стоимости молока в средней полосе России от скорости сборки апельсинов во Вьетнаме. В данном примере показана логика использования данной схемы, не указан только момент останова, но, думаю, это будет всего-лишь проверка
Код
C++ (Qt)
if (promise.isCanceled()) return
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #25 : Май 25, 2020, 10:41 »

А! Т.е. qHash имитирует одну итерацию расчетв. Действительно, все просто, это я туплю Улыбающийся

Ну хорошо, а что, QtConcurrent не обеспечивает этого ф-ционала (отмена/пауза)? (видел там подобные методы). Откуда возникла необходимость (или энтузиазм) юзать недокументированные фичи?
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #26 : Май 25, 2020, 17:53 »

А! Т.е. qHash имитирует одну итерацию расчетв. Действительно, все просто, это я туплю Улыбающийся

Ну хорошо, а что, QtConcurrent не обеспечивает этого ф-ционала (отмена/пауза)? (видел там подобные методы). Откуда возникла необходимость (или энтузиазм) юзать недокументированные фичи?

Функции  типа map(), reduce() умеют, а вот QtConcuent::run() не умеет, так как не передает QFutureInterface в юзерскую функцию. Вот этот хедер из QtCreator'а делает ровно то же самое, что делает QtConcuent::run(), только первым параметром передает QFutureInterface. Это в нем юзается повсеместно - например, когда парсится проект и бежит прогрессбар справа в углу - это вот оно (да, QFutureInterface еще умеет и прогресс репортить).
Записан
alexu007
Чайник
*
Offline Offline

Сообщений: 58


Просмотр профиля
« Ответ #27 : Май 29, 2020, 23:07 »

Пауза:

Код
C++ (Qt)
void Widget::pause(int ms)
{
   QEventLoop el;
   QTimer t;
   connect(&t, SIGNAL(timeout()), &el, SLOT(quit()));
   t.start(ms);
   el.exec();
}
Записан
Страниц: 1 [2]   Вверх
  Печать  
 
Перейти в:  


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