IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C++ Discussion :

Discussion sur le projet d'un ordonnanceur


Sujet :

C++

  1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    amateur
    Inscrit en
    Octobre 2024
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : amateur
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Octobre 2024
    Messages : 2
    Points : 1
    Points
    1
    Par défaut Discussion sur le projet d'un ordonnanceur
    Bonjour,

    Je suis un débutant en programmation C++, j'ai commencé à m'y interésser grace aux Arduino.
    J'ai comme projet de réalisé un petit ordonanceur très léger. Il a pour but de minimisé le temps d'utilisation du processeur, en différants les appels des fonctions, par des appels periodique ou en m'assurant que la fonction ne soit executer qu'une seul fois.

    Le code que je vous soumet est sous forme de header. j'ai commencer à faire des ébauches, il y a un peu plus d'un ans, à l'origine il était voué à tourné sur un Arduino architecture AVR, ce que je vous propose aujourd'hui utilise windows mais ça n'a pas vraiment d'importance pour l'instant, je me concentre sur le concepte et il n'est pas terminer.

    Je n'est pas de probleme particulier avec le code que je vous présente, mais comme je suis un perfectioniste. Malgré n'avoir aucune formation en C++, je suis autodidacte et j'use et abuse de chat GPT pour rédiger le code.
    Je sousmet mon projet à des personnes bienveillante pour me conseillez, pour en débattre... N'hesité pas à me dire si je fait n'importe quoi je ne le prendrais pas mal mais argumenter.

    Voici la methode principale de la class SoftwareEngine / du header :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    void SoftwareEngine::Start() {
        while (true) {
            std::vector<Task*> tasksToExecute;
            Task* nextTask = nullptr;
     
            // Vérifier les tâches prêtes et déterminer la prochaine tâche
            CheckTasks(tasksToExecute, nextTask);
     
            if (!tasksToExecute.empty()) {
                ExecuteTasks(tasksToExecute);
            } else if (nextTask) {
                ExecuteNextTask(nextTask);
            }
        }
    }
    Je vous met une autre methode importante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    void SoftwareEngine::CheckTasks(std::vector<Task*>& tasksToExecute, Task*& nextTask) {
        UpdateCurrentTime();
     
        uint64_t nextTime = UINT64_MAX;
     
        tasksToExecute.clear();
        nextTask = nullptr;
     
        for (auto& task : taskList) {
            if (task.nextExecution <= currentTime) {
                tasksToExecute.push_back(&task);
            } else if (task.nextExecution < nextTime) {
                nextTime = task.nextExecution;
                nextTask = &task;
            }
        }
    }
    Merci d'avance pour vos réponse

    PS : liens pastbin du code complet
    https://pastebin.com/zp8rzkFy = SoftwareEngine.cpp
    https://pastebin.com/7pz03Tkz = SoftwareEngine.h

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 210
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 210
    Points : 12 381
    Points
    12 381
    Par défaut
    Pourquoi réinventer une roue carrée ? (Rien d'agressif, juste savoir si vous avez fait un travail bibliographique de ce qui existait déjà avant )

    Avantages par rapport aux ordonnanceurs déjà présent dans les OS ? Portabilité ?
    Quid du multi-threading ?
    Quid du multi-cœur ?
    Cohabitation avec les ordonnanceurs des OS hôtes ou de frameworks rependus ?
    Différences et analogies avec des types d'ordonnanceurs existants ?

    J'ai pas l'impression que tout ce code soit bien thread-safe.
    Pourquoi tant de pointeurs nues ?
    Pourquoi passer des paramètres à la fonction "SoftwareEngine::CheckTasks", vu qu'ils ne servent à rien (en tant que paramètre). Et ça "Checks" vraiment des "Task" (ou Taske des Checks ) ??? Attention aux noms SVP.

    Et la plus grosse horreur, selon moi, une attente active bien grasse !!! WTF !!!

    C'est quoi votre modèle de conception cible, SVP ??? (modèle de mémoires, de threading, parallélisation CPU-GPU co-Proc, etc...)

    P.S.: Avez-vous déjà fait un programme de test de votre ordonnanceur ?
    Car, pour moi, votre ordonnanceur est inutilisable dans les faits.
    Moi, j'ai tendance à concevoir le code client d'une classe/fromework,bidule + tests unitaire ad hoc avant d'implémenter la moindre ligne du machin, pour ne pas fabriquer une usine à gaz.

  3. #3
    Nouveau Candidat au Club
    Homme Profil pro
    amateur
    Inscrit en
    Octobre 2024
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : amateur
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Octobre 2024
    Messages : 2
    Points : 1
    Points
    1
    Par défaut
    Bonsoir merci de votre retour.

    Pourquoi réinventer une roue carrée ? (Rien d'agressif, juste savoir si vous avez fait un travail bibliographique de ce qui existait déjà avant )
    Le travail bibliographique est limiter aux Arduino,
    il existe effectivement des ordonnenceurs pour Arduino 8bit comme la bibliotheque scheduler :
    https://forum.arduino.cc/t/partage-l...heduler/382567 << le header ici
    Ou encore freertos qui fonctionne sur des architecture de 32bit...

    Le probleme de ces ordonnenceurs existant c'est qu'il ne sont pas adapté à un tout petit processeur de 8bit ou et scheduler n'est pas assez précis millis VS µ

    Quid du multi-threading ?
    Quid du multi-cœur ?
    Je n'envisagait pas d'utilisé le multi-threading.

    Cohabitation avec les ordonnanceurs des OS hôtes ou de frameworks rependus ?
    tu me pose une colle, je ne sais pas.

    J'ai pas l'impression que tout ce code soit bien thread-safe.
    Pourquoi tant de pointeurs nues ?
    Pardone moi mon ignorance mais c'est quoi un pointeurs nue?

    Pourquoi passer des paramètres à la fonction "SoftwareEngine::CheckTasks", vu qu'ils ne servent à rien (en tant que paramètre). Et ça "Checks" vraiment des "Task" (ou Taske des Checks ) ??? Attention aux noms SVP.
    Pour les noms des fonctions et des variables, je ne suis pas tres au faites des conventions, de mon points de vue cette fonction parcours une liste qui contient des taches 'Task' et verifie 'check' si elle sont prete à être executer et en même temps détermine la tache la plus proche. Si tu as une proposition de nom, je t'en pris.
    Pour ce qui est des parametres de la fonction "SoftwareEngine::CheckTasks" Je ne sais pas si tu me dit qu'ils ne servent à rien (en tant que paramètre)...
    Voudrait tu dire qu'il ne sert a rien de faire une fonction pour ça ?

    Et la plus grosse horreur, selon moi, une attente active bien grasse !!! WTF !!!
    Si tu faire referance à :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    boost::this_thread::sleep_for(boost::chrono::microseconds(timeUntilNextExecution));
    N'y prete pas attention c'est pour la déco pour l'instant.

    C'est quoi votre modèle de conception cible, SVP ??? (modèle de mémoires, de threading, parallélisation CPU-GPU co-Proc, etc...)
    Je n'avais pas de model de conception, tu parle des patrons de conception ou un schema avec des rectangles et des losanges ?

    Avez-vous déjà fait un programme de test de votre ordonnanceur ?
    Non, mais ça ne serais pas tres compliqué a faire, juste un peu long a faire.

    Car, pour moi, votre ordonnanceur est inutilisable dans les faits.
    Tu preche un convaincu...

    Moi, j'ai tendance à concevoir le code client d'une classe/fromework,bidule + tests unitaire ad hoc avant d'implémenter la moindre ligne du machin, pour ne pas fabriquer une usine à gaz.
    Oui c'est tres bien de faire ça mais avec mes petit moyen, je n'ai pas compris une bonne partie de la phrase...

  4. #4
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 282
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 282
    Points : 11 036
    Points
    11 036
    Par défaut
    Salut,

    Il y a plusieurs points qui me titillent. Dans le désordre.

    a- Beaucoup de pointeurs bruts. Qui est responsable? Ici il semblerait que cela soit géré à l'extérieur. Aimant la clarté je préfère manipuler des choses comme std::experimental_observer_ptr (pas compliqué à définir)

    b- Pas sur que le vecteur soit ce qu'il y a de mieux pour implémenter des queues de taches. On tend à préférer l'abstraction std::queue

    c- Fuis les paramètres sortants, d'autant plus si tu ne retournes rien. =>
    Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Task * const nextTask = check_tasks(tasks_to_execute);

    d- Mais... Je trouve la suite alambiquée accessoirement. Soit on récupère une tache et on l'exécute. Soit on attend (tranquillement!! Important). Le cote soit il y a des taches que l'on exécute soit il y a une prochaine tache. C'est excessivement bizarre. Et donc non maintenable AMA sur le long terme.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  5. #5
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 210
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 210
    Points : 12 381
    Points
    12 381
    Par défaut
    Le probleme de ces ordonnenceurs existant c'est qu'il ne sont pas adapté à un tout petit processeur de 8bit ou et scheduler n'est pas assez précis millis VS µ
    Généralement, il y a 2 approches.
    - on fait un ordonnanceur "spécifique", il faut donc avoir une application pour tester le bignou dans son aspect.
    - on fait un ordonnanceur "générique" et là, on essaye de tirer le maximum de ce que donne le ou les hardwares cibles tout en proposant une API d'utilisation "standard".
    Là, je vois aucune de ces approches en actions, c'est peut-être pour cela que vous ne trouvez pas chaussure à votre pied : c'est quoi votre pied ?

    Je n'ai pas d'expérience en 8bits mais je ne vois pas en quoi votre ordonnanceur est adapté à du 8bits ni à un temps de réponse "rapide", car, il me semble, il passe toujours le scheduler de l'OS ou l'implémentation ad hoc de la plateforme hardware (cf. l'appel à "boost::this_thread::sleep_for").

    Je trouve les remarques de @Luc Hermitte très justes.

    On a l'impression d'avoir affaire à un mouton à 5 pattes.
    Il est différent des autres mais on ne sait pas pourquoi il serait meilleurs que les autres.

    Quid du multi-threading ?
    Quid du multi-cœur ?
    Je n'envisagait pas d'utilisé le multi-threading.

    Cohabitation avec les ordonnanceurs des OS hôtes ou de frameworks rependus ?
    tu me pose une colle, je ne sais pas.
    Je pense que vous mettez la charrue avant les bœufs.
    Déterminez le "problème à résoudre" avant de concevoir "un machin" qui, potentiellement, ne le résoudra pas. => faire un POC (Proof Of Concept) donc une application test AVANT.
    Plutôt que de bricoler un truc "peut-être utilisable", il faut implémenter ce qui distingue votre machin du reste, pour savoir tout de suite si vous faites fausse route => la manière de "temporiser" vos tâches est primordiales.
    Et vous nous dite que "boost::this_thread::sleep_for", c'est pour la déco ???

    Pardone moi mon ignorance mais c'est quoi un pointeurs nue?
    C'est comme les pointeurs bruts de @Luc Hermitte, c'est des pointeurs "classique" à la C, pas intelligents/smarts. On ne peut pas faire de la programmation "moderne" en C++ sans connaître les smart pointeurs (pointeurs intelligents).
    Même sur une plateforme ne les offrants pas (des vieux runtime C), il faut savoir à quoi ils servent pour émuler leurs "qualités".(ownership, etc...)

    Pour les noms des fonctions et des variables, je ne suis pas tres au faites des conventions, de mon points de vue cette fonction parcours une liste qui contient des taches 'Task' et verifie 'check' si elle sont prete à être executer et en même temps détermine la tache la plus proche. Si tu as une proposition de nom, je t'en pris.
    Pour ce qui est des parametres de la fonction "SoftwareEngine::CheckTasks" Je ne sais pas si tu me dit qu'ils ne servent à rien (en tant que paramètre)...
    Voudrait tu dire qu'il ne sert a rien de faire une fonction pour ça ?
    Ok, elle "parcours une liste", mais ce n'est pas celle passé en paramètre (le std::vector "tasksToExecute"), qui n'est qu'un "paramètre" de sortie. Sa valeur en entré est systématiquement écrasée, donc aucun intérêt en paramètre d'entré, c'est une valeur de sortie. Et c'est la même chose pour le paramètre "nextTask", c'est aussi une valeur de sortie.
    "SoftwareEngine::CheckTasks" elle "parcours une liste", ok, mais on ne l'appel pas pour ça, mais pour sélectionner les tâches à exécuter.
    Donc un nom comme "SelectTask(s)", c'est plus "logique".
    Algorithme de sélection très étrange :
    - S'il y a des tâches en retard, les exécuter toutes dans leur ordre d'insertion dans la liste de tâches, pas en fonction de leur temps de retard.
    - S'il n'y a pas de tâche en retard, exécuter la tâche "en avance" la moins "en avance" après avoir attendu un temps plus ou moins imprécis via l'OS ou via un runtime ad hoc.
    Il n'y a aucun moyen pour les tâches de gérer la dérive temporelle
    Il se passe quoi quand toutes les tâches ont "disparues" ? Ou s'il n'y en a aucune au démarrage ?
    Le fait d'avoir un ordonnanceur "coopératif", ça me dit que c'est vraiment utilisable que pour des projets "jouets".
    On n'est plus sous Win3.11, et encore, il y avait la notion de "fibre" dans de type d'OS.

    Je ne vois pas trop l'intérêt de cet ordonnanceur car soit il utilise l'OS et il aura les mêmes défauts que les ordonnanceurs que vous voulez "éviter" (en plus de toutes les limitations de votre implémentation) ; soit il fera un "spinlock" (une attente active) qui vous fera dégager par tout "antivirus correcte".

    Et la plus grosse horreur, selon moi, une attente active bien grasse !!! WTF !!!
    Si tu faire referance à :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    boost::this_thread::sleep_for(boost::chrono::microseconds(timeUntilNextExecution));
    N'y prete pas attention c'est pour la déco pour l'instant.
    Non, c'est le :
    Et le "boost::this_thread::sleep_for", c'est le cœur même de vôtre machin, s'il ne fait pas "bien" ce que vous voulez mais que vous ne trouvez pas d'autres moyens, vous êtes dans le caca.
    C'est toute l'utilité du POC, prouver que votre idée et faisable, viable, efficace, etc...

    Je n'avais pas de model de conception, tu parle des patrons de conception ou un schema avec des rectangles et des losanges ?
    Il faut au moins savoir quel problème on cherche à régler, avec quelles limitations "acceptables", avec quelles briques de bases et "comment" les utilisateurs "devraient" s'en servir efficacement.
    Ici, on sait même pas si les temporisations fonctionneront "convenablement" pour vos contraintes !

    Non, mais ça ne serais pas tres compliqué a faire, juste un peu long a faire.
    Si un POC est "un peu long a faire", c'est vraisemblablement que la mise en œuvre de votre "solution" demande "trop" de travail.
    Pourquoi votre API n'est pas simple à mettre en œuvre ?

    Oui c'est tres bien de faire ça mais avec mes petit moyen, je n'ai pas compris une bonne partie de la phrase...
    Commencez par faire un POC.

Discussions similaires

  1. Combien d'heures passez vous sur vos projets
    Par Issam dans le forum Débats sur le développement - Le Best Of
    Réponses: 76
    Dernier message: 09/12/2007, 20h53
  2. question sur un projeté orthogonal:)
    Par floflo69 dans le forum Algorithmes et structures de données
    Réponses: 6
    Dernier message: 19/04/2005, 18h06
  3. Réponses: 6
    Dernier message: 31/01/2005, 00h48
  4. Discussions sur la (les) syntaxe(s)
    Par Laurent Dardenne dans le forum Sepi
    Réponses: 11
    Dernier message: 02/01/2005, 21h25

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo