간단한 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으로 제한하는 데 사용 하므로 두 대기 함수는 많은 시간을 기다리지 않습니다.
문제는:
평균 CPU 사용량은 약 0.1 %입니다. 때로는 쿼드 코어 PC에서 25 %까지 올라갑니다. 대기 기능은 테스트 및 설정 기능이있는 while 루프이므로 while 루프는 모든 CPU 리소스를 사용하기 때문에 스레드가 다른 스레드를 기다리고 있음을 의미합니다.
내 첫 번째 질문은 두 스레드를 동기화하는 다른 방법이 있습니까? std::mutex::lock
리소스를 잠그기를 기다리는 동안 CPU를 사용하지 않아서 while 루프가 아닌 것을 알았습니다 . 어떻게 작동합니까? std::mutex
한 스레드에서 잠금을 해제하고 다른 스레드에서 잠금을 해제해야하기 때문에 사용할 수 없습니다 .
다른 질문은; 프로그램이 항상 60 FPS로 실행되기 때문에 때때로 CPU 사용량이 25 %로 증가하는 이유는 두 대기 중 하나가 많이 기다리고 있다는 의미입니다. (두 스레드는 모두 60fps로 제한되므로 이상적으로 많은 동기화가 필요하지 않습니다).
편집 : 모든 답장을 보내 주셔서 감사합니다. 먼저 렌더링을 위해 각 프레임마다 새 스레드를 시작하지 않는다고 말하고 싶습니다. 처음에는 업데이트와 렌더 루프를 모두 시작합니다. 멀티 스레딩은 시간을 절약 할 수 있다고 생각합니다 .FastAlg () 및 Alg () 함수가 있습니다. Alg ()는 내 업데이트 obj 및 렌더 obj이며 Fastalg ()는 "렌더링 큐 보내기"렌더러 ""입니다. 단일 스레드에서 :
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()
}
그러나 이것은 모든 CPU를 사용하는 무한 while 루프가 될 것입니다. 사용을 제한하기 위해 sleep (숫자 <15)을 사용할 수 있습니까? 이러한 방식으로 예를 들어 100fps에서 실행되며 업데이트 기능은 초당 60 회만 호출됩니다.
두 개의 스레드를 동기화하기 위해 createSemaphore와 함께 waitforsingleobject를 사용하므로 다른 스레드에서 잠그고 잠금을 해제 할 수 있습니다 (while 루프를 사용하여 엉클 림).