2012-04-24 12 views
12

Quanto è lungo un singolo giro in C#? Quello che voglio sapere è che c'è un ManualResetEventSlim che ha un parametro spinCount e voglio sapere per quanto tempo ogni giro è in millisecondi o come funziona? So che la rotazione è più efficiente per brevi attese di un kernel in attesa. Quindi sto solo cercando di vedere a cosa dovrei impostare questo valore per un lavoro che generalmente richiede 2-10 sec.Quanto è lungo un singolo spin in ManualResetEventSlim

+0

2-10 .. cosa? Intendevi microsecondi? –

+4

Lo spinning è in nanosecondi e semplicemente non lo fai per 2-10 secondi ... nemmeno per 2-10 millisecondi. –

risposta

24

Non v'è alcuna correlazione tra spinCount parametro nel costruttore e il numero di millisecondi trascorsi a fare un giro di attesa.

Ecco come funziona. MRES utilizza questo parametro spinCount per passare attraverso la propria routine di attesa indipendente da Thread.SpinWait.

  • Le prime 10 iterazioni si alternano tra chiamare Thread.Yield e Thread.SpinWait.La chiamata a Thread.SpinWait inizia con una rotazione di Environment.ProcessorCount * 4 e quindi approssimativamente raddoppia a ogni chiamata successiva.
  • Successivamente ogni iterazione è divisibile per 20 chiamate Thread.Sleep(1).
  • Altrimenti quelli divisibili per 5 chiamate Thread.Sleep(0).
  • Altrimenti viene chiamato Thread.Yield.
  • Il CancellationToken viene controllato ogni 10 iterazioni dopo 100.

Quindi, come potete vedere non v'è abbastanza complessa canzone e danza in corso all'interno di routine di filatura personalizzato di MRES. E l'algoritmo potrebbe cambiare da versione a versione. Non c'è davvero alcun modo di prevedere per quanto tempo ogni giro durerà.

Se i tempi di attesa tipici sono 2-10 secondi, poi il codice è quasi certamente sta per fare un livello di kernel di attesa tramite Monitor.Wait e Monitor.Pulse coordinamenti perché il parametro spinCount è limitata a 2047 comunque.

Inoltre, 2-10 secondi è un tempo lungo. Vuoi davvero girare così a lungo?

+0

+1 per dettagli interessanti. Cerca davvero di ottenere l'altro thread per rilasciare il blocco! –

+0

Posta via, a patto che non ti aspetti che risponda allo Vorrei saperlo anch'io. Nelle strane occasioni in cui ho usato sleep (0)/sleep (1), (solo per il debug), non ho visto differenze nelle prestazioni. –

+0

"approssimativamente"? – Gabe

12

Il numero di giri è pensato per essere piccolo. Il valore predefinito è 10 (o 1 se in esecuzione su un singolo processore). Se si utilizza il costruttore che consente di specificare il numero di spin, il massimo consentito è 2047. Se l'evento non viene segnalato molto rapidamente, ManualResetEventSlim utilizza un normale handle di evento wait. Come ha detto @HenkHolterman, i tempi sono molto, molto più piccoli di secondi. Stiamo parlando di cicli, non di secondi o addirittura di millisecondi.

http://msdn.microsoft.com/en-us/library/5hbefs30.aspx

Nella versione .NET Framework 4, è possibile utilizzare la classe System.Threading.ManualResetEventSlim per migliorare le prestazioni quando i tempi di attesa dovrebbero essere molto breve, e quando l'evento fa non attraversare un confine di processo. ManualResetEventSlim utilizza occupato lo spinning per un breve periodo mentre attende che l'evento venga segnalato. Quando i tempi di attesa di sono brevi, la rotazione può essere molto meno costosa dell'attesa di utilizzando gli handle di attesa. Tuttavia, se l'evento non viene segnalato entro un determinato periodo di tempo, ManualResetEventSlim ricorre a un evento di gestione evento regolare .

http://msdn.microsoft.com/en-us/library/ee722114.aspx

Nei computer multicore, quando una risorsa non dovrebbe essere tenuto per lunghi periodi di tempo, può essere più efficiente per un attesa filo a girare in modalità utente per un poche decine o poche centinaia di cicli, , quindi riprovare per acquisire la risorsa. Se la risorsa è disponibile dopo la rotazione, hai salvato diverse migliaia di cicli. Se la risorsa non è ancora disponibile, hai trascorso solo alcuni cicli e puoi ancora inserire un'attesa basata sul kernel.

MODIFICA: Per rispondere alla domanda direttamente, il tempo per una singola rotazione non può essere risolto in modo definitivo, poiché dipende dall'hardware su cui è in esecuzione. http://msdn.microsoft.com/en-us/library/system.threading.thread.spinwait(v=vs.95).aspx

SpinWait mette essenzialmente il processore in un ciclo molto stretto, con il numero di loop specificato dal parametro iterazioni. La durata di l'attesa dipende quindi dalla velocità del processore.