Я створюю простий 2D ігровий движок, і хочу оновити спрацьовувати спрайти в різних потоках, щоб дізнатися, як це робиться.
Мені потрібно синхронізувати оновлення та рендер. В даний час я використовую два атомних прапора. Робочий процес виглядає приблизно так:
Thread 1 -------------------------- Thread 2
Update obj ------------------------ wait for swap
Create queue ---------------------- render the queue
Wait for render ------------------- notify render done
Swap render queues ---------------- notify swap done
У цій установці я обмежую FPS потоку візуалізації лише FPS потоку оновлення. Крім того, я використовую sleep()
для обмеження FPS рендеринга та оновлення потоку до 60, тому дві функції очікування не чекатимуть багато часу.
Проблема полягає в наступному:
Середнє використання процесора становить близько 0,1%. Іноді це досягає 25% (у чотирьохядерному ПК). Це означає, що потік чекає іншого, оскільки функція очікування - це цикл часу з функцією тестування та встановлення, а цикл "час" використовуватиме всі ваші ресурси процесора.
Перше моє запитання: чи є інший спосіб синхронізації двох потоків? Я помітив, що std::mutex::lock
не використовуйте процесор, поки він чекає, щоб заблокувати ресурс, тому це не цикл часу. Як це працює? Я не можу використовувати, std::mutex
тому що мені потрібно буде зафіксувати їх в одній нитці та розблокувати в іншій потоці.
Інше питання: оскільки програма працює завжди зі швидкістю 60 кадрів в секунду, чому іноді її використання процесора підскакує до 25%, це означає, що один з двох очікувань багато чекає? (обидва потоки обмежені до 60 кадрів в секунду, тому в ідеалі їм не знадобиться багато синхронізації).
Редагувати: Дякую за всі відповіді. Спершу хочу сказати, що я не запускаю новий потік для кожного кадру для візуалізації. Я запускаю і оновлення, і цикл візуалізації на початку. Я думаю, що багатопотоковість може заощадити деякий час: у мене є такі функції: FastAlg () та Alg (). Alg () - це і мій obj Update, і rend obj. В одну нитку:
Alg() //update
FastAgl()
Alg() //render
Двома потоками:
Alg() //update while Alg() //render last frame
FastAlg()
Тож, можливо, багатопоточність може заощадити той же час. (насправді в простому математичному додатку це робиться, де alg - це довгий алгоритм, а amd fastalg - швидший)
Я знаю, що сон не є хорошою ідеєю, хоча у мене ніколи не виникає проблем. Чи буде це краще?
While(true)
{
If(timer.gettimefromlastcall() >= 1/fps)
Do_update()
}
Але це буде нескінченний цикл у той час, як буде використовуватися весь процесор. Чи можу я використовувати сон (число <15), щоб обмежити використання? Таким чином він працюватиме, наприклад, зі 100 кадрів в секунду, а функція оновлення буде викликатися всього 60 разів за секунду.
Для синхронізації двох потоків я буду використовувати waitforsingleobject з createSemaphore, щоб я міг блокувати та розблокувати в різних потоках (без використання циклу в той час), чи не так?