Hi Folks:

I feel that channel preferences are little explained. Based on the earlier 
conversations about channel preference, I have written an initial channel 
preferences document. Please review the document and give comments. When the 
document is correct, I will draw diagrammes and it add to the Wiki.

Channel Preferences

1.0 Introduction:

  The purpose of the channel preference is to provide a form of scheduling 
priority for tasklets. The channel preference is a channel object attribute. 
The channel preference is used as follows: 

ch = stack.channel()
ch.preference = PREFERENCE

PREFERENCE is an integer in the range {-1, 0, 1} where

-1 Receiver preference
0  no preference
1  Sender preference 

receiver preference (-1) is the default value.

1.1 Review of The Scheduling Algorithm

   In order to understand channel preferences, a review of the scheduling 
algorithm is required. Stackless documentation describes the scheduling 
algorithm as 'round-robin.' Tasklets than can be scheduled (or executed) are 
held on the runnables list. The runnable list is a circular doubly 
linked. The stackless.getcurrent() method returns the head or currently 
executing tasklet. 
 
<Illustration>

   When a runnable tasklet yields (i.e., calls stackless.schedule), it is 
placed at the end of the runnable list. Then the next runnable tasklet is 
scheduled. If the currently executing tasklet performs a channel operation that 
will cause it to block, it is taken off the runnable list and transferred to 
the channel's queue.   

<Illustration>

   When there are tasklets in a channel's queue, channel preferences come into 
play.

2.0 Channel Preference Explained

   To illustrate how channel preferences work, four scenarios will be examined. 
Note: a tasklet performing a channel.send() will be called the sender. A 
tasklet performing a channel.receive() will be called a receiver.

2.2 Current tasklet is a Sender, blocked Receiver, Sender Preference 

    Data is transferred to the receiver. The receiver is unblocked and placed 
at the end of the runnables' list. The sender continues executing.

2.3 Current tasklet is a Sender, blocked Receiver, Receiver Preference

     Data is transfered to the receiver. The receiver is unblocked and made the 
current tasklet. The receiver is scheduled.

2.4 Current Tasklet is a Receiver, blocked Sender, Sender Preference

    Data is transferred to the receiver. The sender is unblocked and made the 
current tasklet. The sender is scheduled.

2.5 Current Tasklet is a Receiver, blocked Sender, Receiver Preference

  Data is transferred to the receiver. The sender is placed to the end of the 
runnable list. The receiver continues executing.

3.0 Conclusion

  Why do channel preferences matter? The choice of channel preference will 
affect various scheduling algorthm metrics. For instance response time (the 
time between an IO request is sent and a response is received). Depending on 
the application, the developer may wish to optimize a particular metric.

  This tutorial will end with the analysis of a programme, preferences.py. 
Preferences.py consists of a single sender, five clients and receiver 
preference. When executing the scheduling sequence was: 

C0,C1,C2,C3,C4,S,C1,S,C2,S,C3,S,C4,S

execution time 2.53314614296 average response:  1.00204200745
  
  With a single sender, five clients and sender preference, the scheduling 
sequence is

C0,C1,C2,C3,C4,S,C0,C1,C2,C3,C4
  
execution time 2.49860596657 average response:  2.49821634293

  Over several runs, the execution time of both configurations will be close. 
However the average response time greatly differ. The reason? With receiver 
preference, a receiver is scheduled the moment data is available. With sender 
preference, receivers are placed at the end the runnable list before being 
scheduled. Once the sender is finished, the receivers will execute.

End.




      
"""
preferences.py

The purpose of preferences.py is to demonstrate how channel preferences
can change scheduling metrics, i.e., average response time

For this example, there is one producer and multiple consumers

usage:
preferences.py preference number_of_consumer_taskets
-1 prefer receiver
1 prefer sender
"""

import sys
import string
import stackless
import time

OUTPUT = True 
rSum = 0.0

def producer(channel):
    pStart = time.time()
    for i in range(0, MAX):
        if OUTPUT:
           print "producer about to send"
        channel.send('a')
        time.sleep(.5)
        if OUTPUT:
           print "producer sent"
    pFinish = time.time() - pStart
    print "%s: %f" % ("producer finished", pFinish) 


def consumer(channel, n):
    global rSum
    cStart = time.time()
    if OUTPUT:
       print "consumer ", n, "about to receive"
    channel.receive()    
    cFinish = time.time() - cStart
    rSum = rSum + cFinish
    if OUTPUT:
       print "consumer ", n, "received", "time: ", cFinish 


if __name__ == "__main__":
   name = {} 
   channel = stackless.channel()
   channel.preference = string.atoi(sys.argv[1]) 
   MAX = string.atoi(sys.argv[2])
 
   start = time.time()

   for i in range(0,MAX):
       t = stackless.tasklet(consumer)(channel, i)
       name[t] = i

   t = stackless.tasklet(producer)(channel)
   name[t] = "producer"

   stackless.run() 
   print "execution time", time.time() - start, "average response: ",rSum/MAX 
  
_______________________________________________
Stackless mailing list
[email protected]
http://www.stackless.com/mailman/listinfo/stackless

Reply via email to