2012-01-02 6 views
7

Ho un programma che utilizza la chiamata APIper far passare un thread per un determinato periodo di tempo.
In breve, simula una telecamera inviando immagini prefissate in memoria. Sto usando Sleep per simulare il frame rate - Sleep(1000/fps)Strano comportamento "sospensione" tra i sistemi

Questo funziona bene nel mio sistema di sviluppo (Intel i5 (1a gen), Win7 64), ma quando lo eseguo su un altro sistema (Intel i7-2600 - SandyBridge), i tempi di sonno sono totalmente diversi e imprecisi.

Per esempio, Sleep(16) posti letto per circa 32ms
Sleep(3) posti letto per 16ms

In passato ho pensato che ci fosse un tempo minimo di sonno in finestre di 15ms ma non ottengono tale limitazione sul mio sistema dev.

Qualsiasi idea?

Inoltre, c'è un modo migliore per ottenere il frame rate del mio simulatore?

+0

Stai parlando di Win32 [ 'Sleep'] (http://msdn.microsoft.com/en-us/library/windows/desktop/ms686298.aspx) function, o la funzione C ['sleep'] (http://pubs.opengroup.org/onlinepubs/009604599/functions/sleep.html) (nota l'involucro del "s")? La tua descrizione suggerisce i primi, i nomi di ortografia/denominazione e (piuttosto generici) dall'altra. –

+0

@ Christian.K - Win32 'Sleep' – Itsik

risposta

7

La funzione sleep garantisce che si dorme per almeno l'importo specificato nella chiamata. Fa in modo che il thread si sospenda, consentendo di passare ad altri thread (governati dalle priorità del thread) nel tempo libero dello scheduler. In altre parole, il thread dormiente è non garantito per l'esecuzione immediatamente dopo il tempo specificato è scaduto, quindi utilizzando sleep per la tempistica accurata dovrebbe essere evitato nel caso generale.

Ci sono modi per ottenere un sonno più preciso su Windows. È possibile chiamare timeGetDevCaps per determinare la risoluzione minima del timer supportato e quindi chiamare timeBeginPeriod una volta all'inizio dell'applicazione per impostare la risoluzione del timer al minimo. Assicurati di chiamare timeEndPeriod prima che l'applicazione esca.

Per ulteriori informazioni, vedere the Sleep function on MSDN.

+0

Ho provato a eseguire' timeBeginPeriod' ma non ha alcun effetto sulla durata. – Itsik

+0

Sei sicuro che ha avuto successo, cioè restituito 'TIMERR_NOERROR' [come descritto su MSDN] (http://msdn.microsoft.com/en-us/library/windows/desktop/dd757624 (v = vs.85) .aspx)? –

1

Invece di fare affidamento su un comportamento del sonno incauro o su funzioni del timer specifiche della piattaforma (che potrebbero funzionare bene, non lo so), è possibile strutturarlo come un ciclo di gioco.

All'interno del ciclo si chiama una funzione per fornire l'ora corrente. Calcoli quanto è trascorso da quando hai disegnato l'ultimo fotogramma e decidi quando eseguire il rendering del fotogramma successivo esattamente al momento giusto. Durante lo sviluppo è necessario misurare il numero effettivo di fotogrammi al secondo e visualizzarlo.

Con questo approccio, è più semplice rendere il codice multipiattaforma e più accurato. Anche il tuo ciclo ha il controllo piuttosto che strutturare il tuo codice come callback del timer che potresti anche preferire.

Lo svantaggio è che un ciclo di "attesa attenta" indica che il processo utilizzerà la CPU per tutto il tempo inutilmente. Per mitigare che puoi cedere la CPU nel tuo ciclo pompando esplicitamente gli eventi dell'interfaccia utente in qualche modo o magari usando un sonno più breve :-).

Se vuoi saperne di più su questo approccio, inizia a cercare su Google il materiale sui loop di gioco.

Ecco alcuni collegamenti essenziali:

http://www.koonsolo.com/news/dewitters-gameloop/

http://gafferongames.com/game-physics/fix-your-timestep/

E una discussione su SO:

https://gamedev.stackexchange.com/questions/1589/fixed-time-step-vs-variable-time-step