LINUX.ORG.RU

Цикл и thread sleep на нужный интервал.

ox55ff ★★★★★
()

Ещё std chrono steady_clock если понадобится.

ox55ff ★★★★★
()

т.е. хочется не тупо спать 20 мсек, а до начала следующего периода?

while (true) {
	auto time_awake = high_resolution_clock::now();
	action();
	auto time_cur = high_resolution_clock::now();
	for (;  time_awake <= time_cur;  time_awake += 1000ms/20);
	this_thread::sleep_until(time_awake);
}

По-поводу стоимости узнать время - ну хз как где, как-то смотрел у себя без оптимизаций, около 0.2 микросекунды получалось. 20 и 0.0002, ну крохи какие-то.

Зы: хотя подозреваю, что вопрос про что-то многопоточное

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

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

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

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

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

oops. Промахнулся вкладкой. Это было к новости про письмо в поддержку RMS.

anonymous
()
#include <chrono>
#include <iostream>
#include <thread>

auto now() { return std::chrono::steady_clock::now(); }

auto next_time(auto t0)
{
    using namespace std::literals;
    auto t1 = t0;
    auto tn = now();
    do {
        t1 += 50ms;
    } while (t1 < tn);
    return t1;
}

int main()
{
    auto t0{now()};
    auto t{t0};

    for (size_t i = 0; i < 20; ++i) {
        t = next_time(t);
        std::this_thread::sleep_until(t);
        std::chrono::duration<double, std::milli> elapsed{now() - t0};
        std::cout << "Elapsed " << elapsed.count() << " ms\n";
    };

    return 0;
}
AlexVR ★★★★★
()
Ответ на: комментарий от anonymous

Ну далеко не всегда всё надо отрисовывать.

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

Зачем? Поспать остаток, или выполнять функцию ещё раз если она i/o bound. От задачи же зависит, автор её слишком абстрактно сформулировал и получил абстрактный ответ.

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

эффективно распараллеливать некоторую логику в играх

Логика не параллелится, т.к. логика последовательна. Логика - это если-то, если-то. Как ты второе если-то начнёшь, пока результат первого не известен.

Большинство игровых задач параллелить смысло КРАЙНЕ МАЛО, т.к. на обмен данными между потоками, раздачу им задач и сбор результатов, защиту от взаимного вредительства уходит больше ресурсов, чем парралелизация экономит.

Вот в этой сложной игруне: http://fintank.ru всего 1 поток с вечным циклом while(true) { usleep (1000000 / 30); } который на каждой итерации смотрит что с чем столкнулось. При этом движущихся объектов порядка 1000, а всего объектов миллионы, а проца всё это ест всего процента 3. Ну и иногда этот usleep() прерывается сетевым вводом, когда юзеры что-то нажимают. Точнее там не совсем usleep, а какой-то pthread_cond_timedwait, чтобы ловить нотификации от epoll-треда, но сути не меняет: параллелить просто нечего или это тупо себе дороже.

hellonik
()

на с++ не можна втекти.

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

почему этого массово не делается и большинство игр жрут не больше 4 потоков

Потому что большинство игр в лучшем случае делают по одному потоку на рендер, инпут и игровую логику (ещё сеть бывает) и на этом успокаиваются. Как правильно - чекай Doom III BFG, там всё красиво сделано, хоть на 128 потоков параллелится.

eagleivg ★★★★★
()

Ну например сделать по процессу(потоку) на каждую функцию, которую надо с такой-то периодичность вызывать, сделать вечный цикл с вызовом функции, и чтоб после каждого вызова функций процесс посылал сам себе SIGSTOP, а какой-то другой процесс(поток) пусть с периодичностью 20 раз в секунду посылает тому процессу SIGCONT, это можно сделать через setitimer() и назначить обработчик сигнала SIGVTALRM, см https://stackoverflow.com/q/16037146. Если процесс, выполняющий твою функцию, не успел что-то там доделать, SIGCONT на него никак не повлияет.

Ну или можно мьютексами, фьютексами, семафорами что-то такое тоже делать.

SZT ★★★★★
()

Где ты сейчас находишься и кто за тобой гонится?

den73 ★★★★★
()

На максимальной доступной скорости, насквозь и прочь, в закат.

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

man 2 set_timer

Нет такого. Есть setitimer(2) и timer_create(2)

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

Если нужно точно соблюдать такие маленькие интервалы, то сожрать цпу это самое правильное решение

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

сорян, но на хромиуме рывки скролла, а на ff совсем синий экран и ничего нет (но это возможно hardened конфиг)

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

Большинство игровых задач параллелить смысло КРАЙНЕ МАЛО,

Вот в этой сложной игруне

С какой стати этот пример характеризует все «большинство игровых задач»? С какой стати эта игра сложная?

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

мне кстати понравилась latency, хорошая реакция на нажатия. Если бы еще экран не дергался

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

Не, это у львовян пуканы горят. Зрада на перемогу зашла.

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

С какой стати этот пример характеризует все «большинство игровых задач»?

Ну там есть всё множество игровых задач.

С какой стати эта игра сложная?

Ну там максимально сложно внутри, сложнее нельзя придумать.

hellonik
()
Ответ на: комментарий от seiken

ах, вот оно что! Так сразу бы и написал :)

Ну дык ёпта, я думал очевидно же.

hellonik
()
Ответ на: комментарий от eagleivg

Так игры давно не делают - подход плохо масштабируется. Параллелизм в современных играх task-based - тело игрового цикла в виде графа задач, без специализаций потоков под конкретные цели.

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

Во, у меня такая же идея была.

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

Не поверишь, до сих пор встречается. А насчет task-based - это как раз про BFG.

eagleivg ★★★★★
()

Как правильно тикать на C++?

Тик так ...

Владимир

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