Differences between revisions 1 and 3 (spanning 2 versions)
Revision 1 as of 2009-04-23 15:14:55
Size: 2074
Editor: lukisi
Comment:
Revision 3 as of 2009-04-27 12:14:58
Size: 3369
Editor: lukisi
Comment:
Deletions are marked like this. Additions are marked like this.
Line 36: Line 36:
Il '''modulo xtime''' facilita questo lavoro implementando una funzione {{{swait}}} che automaticamente intervalla uno sleep di 0.001 secondi con una chiamata micro_block fino a quando non è passato il tempo richiesto. Qui ci si trova davanti ad una scelta. Quanto tempo aspettare nella chiamata bloccante {{{time.sleep}}}?
Line 38: Line 38:
Notare inoltre che in questo modulo sia la funzione {{{swait}}} sia la funzione {{{time}}} usano come unità il millisecondo, invece del secondo come nel modulo standard '''time'''. ('''''TODO''': C'è un motivo particolare?'') Se la '''verifica della condizione''' è '''molto impegnativa''', allora '''un tempo basso''' nella sleep è controproducente per l'intero sistema. Infatti ogni pochi istanti la CPU viene impegnata per verificare la condizione, mentre forse sarebbe sufficiente al programma effettuare una verifica ad intervalli più ampi.
Line 40: Line 40:
{{{ xtime.swait(500)}}} Si sarebbe portati quindi a usare '''un tempo alto''' nella sleep. Ma questa chiamata è bloccante per tutto il programma, quindi un tempo alto ostacola inutilmente il procedere degli altri microthread.

Se invece la '''verifica della condizione''' risultasse '''non impegnativa''', allora usare un tempo basso sarebbe la risposta ottimale.

Il '''modulo xtime''' facilita questo lavoro implementando una funzione {{{swait}}} che automaticamente intervalla uno sleep di 0.001 secondi con una chiamata micro_block fino a quando non è passato il tempo richiesto. La verifica da fare è poco onerosa, si tratta di leggere l'ora del sistema.

Notare inoltre che nel modulo '''xtime''' sia la funzione {{{swait}}} sia la funzione {{{time}}} usano come unità il millisecondo, invece del secondo come nel modulo standard '''time'''. ('''''TODO''': C'è un motivo particolare?'')

In conclusione:
 * se la condizione da verificare è poco onerosa, intervallarla con una chiamata a {{{time.sleep}}} con un tempo basso espresso in secondi e una chiamata a {{{micro_block}}}
 * se la condizione da verificare è molto onerosa, intervallarla con una chiamata a {{{xtime.swait}}} con un tempo più alto espresso in millisecondi
 * se non ci sono condizioni da verificare, ma solo si vuole attendere un certo tempo, usare {{{xtime.swait}}}

Il modulo xtime

Il modulo ntk.lib.xtime (TODO: replicato in ntk.wrap.xtime, perché?) risponde al problema dell'uso di sleep in un ambiente di multithread cooperativo.

Quando un microthread ha la necessità di attendere alcuni istanti prima di eseguire una certa azione, come lo fa?
Supponiamo si vuole attendere una certa condizione.

Può eseguire

    while not my_condition():
        pass

Questa è una cosidetta busy-wait. Il sistema viene appesantito, perché fino a quando la condizione non diventa vera il processo impegna la CPU.

Di norma si evita questo spreco inserendo dei piccoli sleep. Ad esempio

    while not my_condition():
        time.sleep(0.01)

Durante questa attesa la CPU non è impegnata. Soltanto una volta ogni 0.01 secondi, che per il processore è molto tempo, fa qualcosa per verificare se la condizione è divenuta vera.
Questa non è più una busy-wait, nel senso che l'intero sistema non viene appesantito. Ma in un ambiente di microthread cooperativi, questo approccio non istruisce lo schedulatore di passare il comando ad altri microthread. Così, anche se il sistema appare scarico, il nostro programma non va avanti.

Va quindi aggiunta una chiamata alla stackless.schedule, che nel nostro programma è nel metodo micro.micro_block().

    while not my_condition():
        time.sleep(0.01)
        micro.micro_block()

Nota: la chiamata a time.sleep resta necessaria, altrimenti ritorneremo ancora ad una situazione di busy-wait.

Qui ci si trova davanti ad una scelta. Quanto tempo aspettare nella chiamata bloccante time.sleep?
Se la verifica della condizione è molto impegnativa, allora un tempo basso nella sleep è controproducente per l'intero sistema. Infatti ogni pochi istanti la CPU viene impegnata per verificare la condizione, mentre forse sarebbe sufficiente al programma effettuare una verifica ad intervalli più ampi.
Si sarebbe portati quindi a usare un tempo alto nella sleep. Ma questa chiamata è bloccante per tutto il programma, quindi un tempo alto ostacola inutilmente il procedere degli altri microthread.

Se invece la verifica della condizione risultasse non impegnativa, allora usare un tempo basso sarebbe la risposta ottimale.

Il modulo xtime facilita questo lavoro implementando una funzione swait che automaticamente intervalla uno sleep di 0.001 secondi con una chiamata micro_block fino a quando non è passato il tempo richiesto. La verifica da fare è poco onerosa, si tratta di leggere l'ora del sistema.

Notare inoltre che nel modulo xtime sia la funzione swait sia la funzione time usano come unità il millisecondo, invece del secondo come nel modulo standard time. (TODO: C'è un motivo particolare?)

In conclusione:

  • se la condizione da verificare è poco onerosa, intervallarla con una chiamata a time.sleep con un tempo basso espresso in secondi e una chiamata a micro_block

  • se la condizione da verificare è molto onerosa, intervallarla con una chiamata a xtime.swait con un tempo più alto espresso in millisecondi

  • se non ci sono condizioni da verificare, ma solo si vuole attendere un certo tempo, usare xtime.swait

Netsukuku/ita/ModuloXtime (last edited 2009-06-05 09:14:24 by lukisi)