2017-07-25 1 views
1

Disons que j'ai 3 tâches:événements discrets SIMULATION DE Embarqué Firmware en utilisant Simpy

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

task2 et TASK3 définis de la même

et moi avons une unité centrale de traitement. Une approche intégrée commune serait de faire ce qui suit:

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

Maintenant, je veux simuler cela dans Simpy, mais je ne veux pas faire défiler en permanence le code round_robin s'il n'y a pas de travail à faire pour l'une des tâches (car cela augmenterait le temps de simulation), mais je veux qu'une seule tâche puisse être exécutée à la fois. En outre, je veux simuler le fait que, lorsque le travail devient disponible, par ex. pour task2, il peut s'écouler un certain temps avant que task2() ne soit exécuté (le processeur est occupé à vérifier si les autres tâches ont du travail à faire/à faire pour d'autres tâches).

Dans Simpy, j'ai défini les tâches telles que chacun a donné un événement (par exemple les éléments de travail à venir dans une file d'attente):

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

Mais si j'utilise env.process(task1()); env.process(task2()); env.process(task3()), ils pourraient tous courir en parallèle, qui ne modélise pas précisément le comportement de la boucle while. Une approche que je pensais être peut-être pour définir une ressource appelée CPU, cpu = Resource(), puis avoir les tâches donnent sur obtenir un work_item et ensuite céder sur obtenir le CPU, puis donner un temps aléatoire entre 0 et 2 * d'autres tâches:

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) 

Mais cela semble un peu en désordre car une tâche doit savoir combien d'autres tâches que le cpu est en cours d'exécution.

Existe-t-il une meilleure façon de modéliser cela? Dois-je avoir un processus de production sur la demande du CPU et ensuite attendre le travail, mais avoir l'attente sur le travail interruptible (de sorte qu'une tâche sans travail ne bloque pas les tâches qui ont du travail)?

Répondre

1

Vous pouvez écrire un processus qui place toutes les tâches dans une file d'attente (par exemple, Store avec une capacité illimitée).

Votre « cpu » peut faire quelque chose comme:

def cpu(env, work_q): 
    while True: 
     task, args = yield work_q.get() 
     yield env.timeout(3) # task setup 
     yield env.process(task(*args)) # run actual task 
+0

Merci, j'ai fini par créer un objet CPU qui hérite de ressources et défini une méthode sur elle appelé bloc. Cpu.block (process_time) génère un processus qui génère lui-même une self.request(), puis renvoie self.env.timeout (process_time). Je puis cpu.block() de mes tâches. – sheridp