lundi 24 juillet 2017

Discrete Event Simulating Embedded Firmware using Simpy

Let's say I have 3 tasks:

def task1():
    if check_if_theres_work_to_do():  #just checking takes 2us
        do_work()  #takes 10us

task2 and task3 defined similarly

and I have one CPU. A common embedded approach would be to do the following:

def round_robin():
    while True:
        task1()
        task2()
        task3()

Now, I want to simulate this in Simpy, but I don't want to constantly cycle the round_robin code if there's no work to do for any of the tasks (as this would increase simulation time), but I want only one task to be able to run at a time. Further, I want to simulate the fact that, when work becomes available, e.g. for task2, it may take some amount of time before task2() gets executed (the processor is busy checking if the other tasks have work to do / actually doing work for other tasks).

In Simpy, I've defined the tasks such that each has yielded on an event (e.g. work items coming in on a queue):

def task1():
    work_item = yield task1_work_queue.get()
    do_task1_work(work_item)

But if I use env.process(task1()); env.process(task2()); env.process(task3()), then they could all run in parallel, which does not accurately model the behavior of the while loop.

One approach I thought might be to define a resource called CPU, cpu = Resource(), and then have the tasks yield on getting a work_item and then yield on getting the cpu, and then yield a random amount of time between 0 and 2*number of other tasks:

def task1():
    work_item = yield task1_work_queue.get()
    with cpu.request() as req:
        yield req
        yield env.timeout(4)
        do_task1_work(work_item)

But this seems kinda messy since a task has to know how many other tasks the cpu is executing.

Is there a better way to model this? Should I have a process yield on requesting the cpu and then waiting on the getting work, but have the wait on work interruptible (so that a task with no work doesn't block tasks that do have work)?

Aucun commentaire:

Enregistrer un commentaire