Vous trouverez ici quelques documents et quelques liens pouvant, je l'espère, vous être utiles. Vous pouvez aussi consulter, parmi les liens divers mis à votre disposition, ceux portant sur les STR, ceux portant sur la multiprogrammation et ceux portant sur l'optimisation.
Les documents qui vous sont fournis ici le sont pour vous rendre service.
Je travaille très fort sur chacun de mes cours. Veuillez ne pas vendre (ou donner) les documents que je vous offre ici à qui que ce soit sans mon consentement. Si des abus surviennent, je vais cesser de rendre ce matériel disponible à toutes et à tous.
Si ces documents vous rendent service, faites-le moi savoir. Mon adresse de courriel est disponible sur la page où on trouve mon horaire.
| IFT611/729 | INF749 |
|
Si vous cherchez l'inspiration, vous trouverez ici quelques exemples des projets qui ont été faits dans ce cours au fil du temps (liste non-exhaustive) |
|
Sur ce site, vous trouverez :
Note d'ordre général
Il arrive que j'aie en classe des étudiant(e)s qui ont déjà suivi des cours avec moi où l'on trouvait un besoin de multiprogrammation ou de programmation générique. Malheureusement, faute de préalables, je ne peux pas supposer que tous et toutes ont les bases nécessaires pour escamoter ces concepts, alors j'implore votre tolérance, surtout pour les deux ou trois premières séances, si vous rencontrez des éléments de matière qui sont, pour vous, du déjà vu.
| Index des séances théoriques | |||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| IFT611/729 | S00 | S01 | S02 | S03 | S04 | S05 | S06 | S07 | S08 | S09 | S10 | S11 | S12 |
| INF749 | S00 | S01 | S02 | S03 | S04 | S05 | S06 | S07 | S08 | S09 | S10 | S11 | S12 |
Pendant les premières séances, nous examinerons surtout des concepts et techniques de base, qui seront réinvestis dans les exemples et les illustrations concrètes que proposera le professeur. Ce sont donc des séances plus près de la (saine) programmation au sens large que des STR de manière spécifique; j'espère que vous saurez voir les concepts propres aux STR même si la praxis sera présente dans notre discours.
D'autres approches sont possibles pour un cours de STR, évidemment, mais le choix pédagogique fait par votre chic prof de discuter à la fois de théorie et de pratique demande de mettre sur pied quelques bases au préalable. Je vous remercie de votre tolérance (et, si vous avez apprécié, alors tant mieux!).
| Séances IFT611/729 | Contenu IFT611/729 | Séances INF749 | Contenu INF749 |
|---|---|---|---|
| S00 – IFT611/729, 9 janvier |
Le mots de la semaine : introduction, vocabulaire et bases. On s'entend sur quelques termes et façons de faire qui nous suivront toute la session Au menu :
Petit complément : j'ai rédigé un petit comparatif de « performances » pour certaines opérations types applicables à un tableau brut, alloué dynamiquement, et à un vecteur standard. Il s'avère que, lorsqu'il est bien utilisé, le vecteur est presque toujours aussi rapide – ou plus rapide! – que son substrat, le tableau brut, parce que le code sous-jacent est extrêmement sophistiqué et parce que nous, programmeurs de tous les jours, ne prenons pas chaque fois le soin de manipuler nos tableaux comme le font en tout temps les concepteurs du vecteur standard. Le dire, bien sûr, c'est une chose, mais le démontrer, c'est mieux, alors jetez un coup d'oeil à ../../Sources/comparatif_vecteur_tableau.html si vous êtes intéressé(e). De même, si vous êtes curieuse / curieux de comparer la vitesse à l'exécution d'une fonction et d'un foncteur à tâche équivalente, voir ../../Sources/Comparaison-Fonctions-Foncteurs.html Dans les notes de cours, vous trouverez de la matière en lien avec cette séance dans STR – Volume 00 (vocabulaire, donc les pages ≈5..35). Truc important : bien que je ne l'aie pas mentionné explicitement pendant la séance, ce cours mettra l'accent sur plusieurs facettes de la conception et du développement de STR, dont :
Ne vous étonnez donc pas de voir ces thématiques apparaître de manière récurrente dans notre discours. Le code écrit durant cette séance était : |
S00 – INF749, 6 janvier |
Le mots de la semaine : introduction, vocabulaire et bases. On s'entend sur quelques termes et façons de faire qui nous suivront toute la session Au menu :
Petit complément : j'ai rédigé un petit comparatif de « performances » pour certaines opérations types applicables à un tableau brut, alloué dynamiquement, et à un vecteur standard. Il s'avère que, lorsqu'il est bien utilisé, le vecteur est presque toujours aussi rapide – ou plus rapide! – que son substrat, le tableau brut, parce que le code sous-jacent est extrêmement sophistiqué et parce que nous, programmeurs de tous les jours, ne prenons pas chaque fois le soin de manipuler nos tableaux comme le font en tout temps les concepteurs du vecteur standard. Le dire, bien sûr, c'est une chose, mais le démontrer, c'est mieux, alors jetez un coup d'oeil à ../../Sources/comparatif_vecteur_tableau.html si vous êtes intéressé(e). De même, si vous êtes curieuse / curieux de comparer la vitesse à l'exécution d'une fonction et d'un foncteur à tâche équivalente, voir ../../Sources/Comparaison-Fonctions-Foncteurs.html Dans les notes de cours, vous trouverez de la matière en lien avec cette séance dans STR – Volume 00 (vocabulaire, donc les pages ≈5..35). Truc important : bien que je ne l'aie pas mentionné explicitement pendant la séance, ce cours mettra l'accent sur plusieurs facettes de la conception et du développement de STR, dont :
Ne vous étonnez donc pas de voir ces thématiques apparaître de manière récurrente dans notre discours. Le code écrit durant cette séance était : |
| S01 – IFT611/729, 16 janvier |
Le mots de la semaine : saines pratiques et hygiène de programmation. On établit des façons de faire, et on examine les nuances entre copie (complexité typiquement linéaire, temps souvent indéterministe) et mouvement (complexité typiquement constante, temps souvent déterministe), tout en introduisant quelques idiomes fort utiles. Au menu, d'une manière teintée par notre besoin d'avoir une approche appropriée pour le développement de STR :
Mise en place d'un premier conteneur (un tableau d'entiers) implémenté selon les conventions du langage C++, en portant une attention particulière aux considérations de robustesse et d'efficacité, incluant :
Munis des idées et techniques mises de l'avant dans cette séance, vous devriez être en mesure de comprendre les exemples dans STR – Volume 01 (voir le code des cas sous étude). Profitez de l'opportunité pour expérimenter avec ces propositions de tests, pour les modifier, pour essayer de comprendre les métriques que vous parviendrez à en tirer, etc. Le code utilisé pour la classe Tableau suit (notez que nous discuterons de grow() à la séance S02) :
Dans les notes de cours, comme mentionné dans le paragraphe précédent, vous trouverez de la matière en lien avec cette séance dans STR – Volume 01. Complément culturel : même les compilateurs ont des bogues (quoiqu'ils en aient sans doute moins que vous ne le croyez parfois). Pour en savoir plus sur un bogue du compilateur sous-jacent à Visual Studio, décrit (avec sa solution) par Stephan T. Lavavej, voir http://channel9.msdn.com/Series/C9-Lectures-Stephan-T-Lavavej-Core-C- (en particulier la partie de ). |
S01 – INF749, 13 janvier |
Le mots de la semaine : saines pratiques et hygiène de programmation. On établit des façons de faire, et on examine les nuances entre copie (complexité typiquement linéaire, temps souvent indéterministe) et mouvement (complexité typiquement constante, temps souvent déterministe), tout en introduisant quelques idiomes fort utiles. Au menu, d'une manière teintée par notre besoin d'avoir une approche appropriée pour le développement de STR :
Mise en place d'un premier conteneur (un tableau d'entiers) implémenté selon les conventions du langage C++, en portant une attention particulière aux considérations de robustesse et d'efficacité, incluant :
Munis des idées et techniques mises de l'avant dans cette séance, vous devriez être en mesure de comprendre les exemples dans STR – Volume 01 (voir le code des cas sous étude). Profitez de l'opportunité pour expérimenter avec ces propositions de tests, pour les modifier, pour essayer de comprendre les métriques que vous parviendrez à en tirer, etc. Le code utilisé pour la classe Tableau suit (notez que nous discuterons de grow() à la séance S02) :
Dans les notes de cours, comme mentionné dans le paragraphe précédent, vous trouverez de la matière en lien avec cette séance dans STR – Volume 01. Complément culturel : même les compilateurs ont des bogues (quoiqu'ils en aient sans doute moins que vous ne le croyez parfois). Pour en savoir plus sur un bogue du compilateur sous-jacent à Visual Studio, décrit (avec sa solution) par Stephan T. Lavavej, voir http://channel9.msdn.com/Series/C9-Lectures-Stephan-T-Lavavej-Core-C- (en particulier la partie de ). |
| S02 – IFT611/729, 23 janvier |
Le mots de la semaine : sélection à coût nul d'algorithmes. Premier contact avec les traits et leurs applications. Au menu :
La classe Tableau avec constructeur et affectation de mouvement suit, et il en va de même pour le test qui met en relief l'impact du mouvement sur la vitesse d'un programme : Notez que notre examen d'implémentations génériques d'un tableau suivra sous peu; nous avons quelques menus détails à explorer auparavant.
Dans les notes de cours, vous trouverez de la matière en lien avec cette séance dans STR – Volume 00, annexes 00 et 01, mais vous en trouverez surtout dans les liens ci-dessus. |
S02 – INF749, 20 janvier |
Le mots de la semaine : sélection à coût nul d'algorithmes. Premier contact avec les traits et leurs applications. Au menu :
La classe Tableau avec constructeur et affectation de mouvement suit, et il en va de même pour le test qui met en relief l'impact du mouvement sur la vitesse d'un programme : Notez que notre examen d'implémentations génériques d'un tableau suivra sous peu; nous avons quelques menus détails à explorer auparavant.
Dans les notes de cours, vous trouverez de la matière en lien avec cette séance dans STR – Volume 00, annexes 00 et 01, mais vous en trouverez surtout dans les liens ci-dessus. |
| S03 – IFT611/729, 30 janvier |
Le mots de la semaine : sélection à coût nul d'algorithmes et résilience. Notre exploration des traits et de leurs applications se poursuit; nous revenons sur le tableau d'entiers pour en faire un tableau générique, et nous examinons les conséquences de ce geste sur la résilience de notre code.
Dans les notes de cours, vous trouverez de la matière en lien avec cette séance dans STR – Volume 00, annexes 00 et 01, mais vous en trouverez surtout dans les liens ci-dessus. La fonction distance() est un cas d'espèce intéressant, tiré du standard lui-même, qui exploite les traits et les catégories pour réaliser une optimisation presque obscène. J'aime bien faire le tour de cette approche, qui peut être appliquée à bien d'autres trucs, avec des gens qui, comme vous, doivent écrire des programmes dont les performances sont sans compromis. Les plus curieuses et les plus curieux remarqueront que les fonctions advance(), next() et prev() appliquent les mêmes techniques d'optimisation que sa cousine distance(). J'ai utilisé la technique du tag dispatching, mais il existe d'autres techniques pour y arriver : On pourrait appliquer d'autres mécanismes, par exemple std::nable_if ou des concepts. Dans ce cas bien précis, le recours à if constexpr pourrait être moins plaisant, du fait qu'il n'y a pas de « cas par défaut » alors la question de ce qui devrait faire partie du else final se poserait (il faudrait probablement combler ce cas – l'escamoter, vraiment avec un static_assert ou quelque chose de semblable). C'est normal : il existe une diversité d'outils pour une diversité de cas d'utilisation, après tout. N'oubliez pas de livrer L00 aujourd'hui! |
S03 – INF749, 27 janvier |
Le mots de la semaine : sélection à coût nul d'algorithmes et résilience. Notre exploration des traits et de leurs applications se poursuit; nous revenons sur le tableau d'entiers pour en faire un tableau générique, et nous examinons les conséquences de ce geste sur la résilience de notre code.
Dans les notes de cours, vous trouverez de la matière en lien avec cette séance dans STR – Volume 00, annexes 00 et 01, mais vous en trouverez surtout dans les liens ci-dessus. La fonction distance() est un cas d'espèce intéressant, tiré du standard lui-même, qui exploite les traits et les catégories pour réaliser une optimisation presque obscène. J'aime bien faire le tour de cette approche, qui peut être appliquée à bien d'autres trucs, avec des gens qui, comme vous, doivent écrire des programmes dont les performances sont sans compromis. Les plus curieuses et les plus curieux remarqueront que les fonctions advance(), next() et prev() appliquent les mêmes techniques d'optimisation que sa cousine distance(). J'ai utilisé la technique du tag dispatching, mais il existe d'autres techniques pour y arriver : On pourrait appliquer d'autres mécanismes, par exemple std::nable_if ou des concepts. Dans ce cas bien précis, le recours à if constexpr pourrait être moins plaisant, du fait qu'il n'y a pas de « cas par défaut » alors la question de ce qui devrait faire partie du else final se poserait (il faudrait probablement combler ce cas – l'escamoter, vraiment avec un static_assert ou quelque chose de semblable). C'est normal : il existe une diversité d'outils pour une diversité de cas d'utilisation, après tout. N'oubliez pas de livrer L00 aujourd'hui! |
| S04 – IFT611/729, 6 février |
Au menu :
|
S04 – INF749, 3 février |
Au menu :
|
| S05 – IFT611/729, 13 février |
Au menu :
|
S05 – INF749, 10 février |
Au menu :
|
| S06 – IFT611/729, 20 février |
Au menu :
|
S06 – INF749, 17 février |
Au menu :
|
| 27 février |
Cours suspendus dans le but de faire place aux examens périodiques pour les cours qui en tiennent |
24 février |
Cours suspendus dans le but de faire place aux examens périodiques pour les cours qui en tiennent |
| 6 mars |
Relâche. Reposez-vous un peu, vous en avez sûrement besoin! |
3 mars |
Relâche. Reposez-vous un peu, vous en avez sûrement besoin! |
| S07 – IFT611/729, 13 mars |
Au menu :
N'oubliez pas de remettre le livrable L01! Attention : exceptionnellement, séance en ligne par Teams |
S07 – INF749, 10 mars |
Au menu :
N'oubliez pas de remettre le livrable L01! |
| S08 – IFT611/729, 20 mars |
Au menu :
Attention : exceptionnellement, séance en ligne par Teams |
S08 – INF749, 17 mars |
Au menu :
|
| S09 – IFT611/729, 27 mars |
Au menu :
Attention : exceptionnellement, séance en ligne par Teams |
S09 – INF749, 24 mars |
Au menu :
|
| 3 avril |
Vendredi Saint, congé universitaire |
S10 – INF749, 31 mars |
Au menu :
|
| S10 – IFT611/729, 10 avril |
Au menu :
|
S11 – INF749, 7 avril |
Au menu :
N'oubliez pas de remettre le livrable L02! |
| S11 – IFT611/729, 17 avril |
Au menu :
N'oubliez pas de remettre le livrable L02! |
S12 – INF749, 14 avril |
Chic examen final plein d'amour |
| S12 – IFT611/729, ?? avril |
Chic examen final plein d'amour, de xx h xx à xx h xx au Dx-xxxx |
Les sections qui suivent proposent du code ou des exemples proposés en classe, le tout dans le but de vous permettre d'étudier la chose, de critiquer, de commenter, de questionner et d'expérimenter à loisir. Notez que certains des exemples ci-dessous doivent être retouchés à la lueur de l'évolution du langage C++.
![]() |
Cliquez sur cette cible pour obtenir le projet bmp00, réalisant une compression RLE sur des bitmaps dans un temps raisonnable. Ce projet n'est pas un STR puisqu'il cherche à réaliser rapidement et correctement une tâche mais n'offre aucune garantie de non-dépassement d'un seuil de temps – il n'y a aucun plafond mesurable dans le temps d'exécution de l'algorithme de compression dans ce programme, donc aucune contrainte de temps dont le respect serait déterministe. L'idée d'offrir d'abord une version opérationnelle d'un algorithme donné, sans se préoccuper de contraintes TR, est que cette version est en général plus simple que les versions offrant des garanties TR strictes. Sur le plan pédagogique, cela donne aussi une excuse à votre professeur pour mettre en place des bases conceptuelles clés du code moderne, pour que toutes et tous comprennent ses exemples, sans aller jusqu'à donner un cours général de techniques de programmation contemporaines. J'essaie de mettre en place des bases conceptuelles et techniques communes sans trop me répéter étant donné la nature bigarrée mais techniquement très solide de la clientèle de ce cours. |
![]() |
Cliquez sur cette cible pour obtenir le projet bmp_morcele, réalisant une compression RLE sur des bitmaps dans un temps raisonnable et de manière à ne pas dépasser un certain seuil de tolérance au temps. Cette version compresse des données RGB brutes selon une approche RLE et peut, contrairement aux deux précédentes, être considérée TR (au sens usuel, pas au sens strict, mais principalement à cause de la plateforme) dans la mesure où le seuil indiquant d'arrêter tiendrait compte du pire cas possible (calculé a priori) pour une séquence de compression RLE donnée. Aller jusque là demanderait toutefois une meilleure connaissance du contexte et obscurcirait quelque peu le propos. Le code du projet est du code de test, montrant qu'il est possible de faire en sorte que l'algorithme de compression s'interrompe « en cours de traitement ». Quelques suggestions d'exercices pour vous faire la main :
|
![]() |
Cliquez sur cette cible pour la description du format bitmap. |
![]() |
Cliquez sur cette cible pour la description de la compression RLE. Pour un peu de pédagogie sur RLE, voir http://hbfs.wordpress.com/2009/04/14/ad-hoc-compression-methods-rle/ |
![]() |
Pour un texte sur le concept, voir ../../Sujets/TempsReel/executifs.html Cliquez sur cette cible pour obtenir les sources d'un projet contenant une ébauche fonctionnelle d'exécutif de simulation. Ce projet a été conçu avec Visual Studio 2022, mais les sources sont essentiellement portables (le fichier source non portable est concis, et je pense que vous n'aurez pas de peine à l'identifier). Un exécutif est un système monoprogrammé qui, avec discipline et avec soin, permet d'atteindre des performances prévisibles et des comportements se rapprochant de ceux qu'on retrouve dans les systèmes multiprogrammés, mais sans payer le prix associés outils de synchronisation. Rien n'est parfait (la mécanique ne peut être répartie sur plusieurs coeurs qu'au prix d'efforts manuels) mais l'idée peut être stimulante et repose sur des techniques qu'on enseigne peu à dans nos institutions aujourd'hui. |
Pour une image frappante, je vous invite à comparer le schéma des états d'un processus qu'on trouve sur le Wiki à ce sujet avec celui que met de l'avant QNX (document d'origine). C'est divertissant.
Notez que l'aide en ligne pour QNX est de très bonne qualité, pour ce système en particulier comme pour les STR en général. La racine pour la version la plus récente de cette aide (à ma connaissance, du moins) est http://www.qnx.com/developers/docs/6.5.0/index.jsp
Pour les séances avec QNX, vous trouverez le code source des illustrations à travers les liens suivants (ce ne sont que de petits exemples pour vous démarrer, sans plus) :
Le lien le plus important est sans doute celui offrant de l'aide sur la bibliothèque standard de la platreforme, soit http://www.qnx.com/developers/docs/6.5.0/topic/com.qnx.doc.neutrino_lib_ref/about.html. Pour la messagerie synchrone, portez une attention particulière au trio d'opérations MsgSend(), MsgReceive() et MsgReply().
De la documentation touffue vous est offerte sur les SETR et sur QNX dans la section à cet effet : http://www.qnx.com/developers/docs/6.5.0/topic/com.qnx.doc.neutrino/bookset.html
À propos du développement TR pour processeurs à plusieurs coeurs, la section http://www.qnx.com/developers/docs/6.5.0/topic/com.qnx.doc.multicore_en/bookset.html peut vous intéresser.
Les sources du code de Double-Buffering et du code du serveur d'entrées/ sorties non-bloquantes sont mises à votre disposition. Désolé de ne pas avoir fait une meilleure présentation, le temps m'a manqué.
Un appareil de type « photo radar » a pour rôle de détecter le mouvement d'un véhicule dans un espace contrôlé et, si la vitesse de déplacement du véhicule en question dépasse un certain seuil, de provoquer une capture d'image qui sera analysée pour détecter un ensemble de caractéristiques (couleur, marque, symboles sur la plaque d'immatriculation, etc.).

En bref, un capteur physique (le radar) saisit les mouvements d'objets dans un espace et les signale à un module d'analyse de première ligne capable de reconnaître un déplacement suspect et de provoquer une demande de capture d'image de la part d'une caméra à haute définition. Une fois l'image capturée, celle-ci est transmise à un module analytique qui en sortira les principales caractéristiques recherchées, puis les intégrera à une base de données. Ensuite, un module produisant des contraventions en fonction des besoins pourra, de manière automatique, faire son travail.
La question est en trois volets :