
Histoire de performance
mer 11 décembre 2024Introduction
Le système IBM i, anciennement appelé AS/400, est largement reconnu pour sa robustesse et sa fiabilité dans les environnements d’entreprise. Grâce à son architecture intégrée unique, il gère efficacement les applications à travers le monde. Cependant, pour tirer le meilleur parti de cette plateforme, il peut être important de comprendre comment optimiser les performances des programmes RPGLE. Cet article présente une étude des tests de performance réalisés sur un IBM i, mettant en lumière l’impact de différentes pratiques de codage sur les temps d’exécution.
Objectif des Tests de Performance
Ces tests ont été réalisés dans le but de comparer les performances de différents fragments de code RPGLE dans un environnement IBM i. L’objectif était de déterminer l’influence de diverses pratiques de programmation, telles que l’utilisation ou non de l’instruction INLR, et d’évaluer l’effet des niveaux d’optimisation sur les temps d’exécution des programmes.
Vue d’ensemble de l’Environnement de Test
Les tests ont été effectués sur un système IBM i de gamme moyenne. Le système exécutait la dernière version du système d’exploitation IBM i(7.5), avec le langage RPGLE pour les scripts de test. Deux fragments de code distincts ont été utilisés, l’un appelant l’autre, pour mesurer les performances en fonction des optimisations appliquées et des structures de programme employées.
Méthodologie des Tests
Pour garantir la précision des résultats, chaque test a été exécuté plusieurs fois dans les mêmes conditions. Le principal indicateur de performance comparé était le temps CPU, mesuré en UC(s) (unités de CPU). Les scénarios évalués comprenaient des appels de programmes standards avec *INLR à *ON, de programme sans instruction INLR, de sous-procédure dans un module de programme multimodule et de sous-procédure contenu dans un Programme de Service (SRVPGM).
Analyse des Fragments de Code
Le premier fragment de code consistait en une boucle simple dans un programme RPGLE, appelant une fonction qui calcule la circonférence d’un cercle. Voici un aperçu du code :
**FREE ctl-opt main(LOOPS) Dftactgrp(*no) actgrp('PERFORM'); Dcl-pr diametreCercle extpgm('DIAMCERCLE'); rayon float(4) const; end-pr; dcl-proc LOOPS; Dcl-pi *n extpgm('LOOPS'); End-pi; dcl-s counter int(10); *inlr = *on; for counter = 1 to 10000000; diametreCercle(6371); endfor; return; end-proc;
L’optimisation de cet aspect peut avoir un impact significatif sur les performances, comme nous le verrons dans les résultats.
Le deuxième fragment de code se concentre sur le calcul de la circonférence dans une procédure séparée.
**FREE ctl-opt Main(diametreCercle) dftactgrp(*no) actgrp('PERFORM'); dcl-proc diametreCercle; dcl-pi *n extpgm('DIAMCERCLE'); rayon float(4) const; end-pi; dcl-s circonference float(4); *Inlr = *On; circonference = 2 * 3.14159 * rayon; return; end-proc;
Exécution
L’appel sera soumis avec la commande SBMJOB dans les mêmes conditions et dont nous pourrons recueillir un spool où est consigné le temps CPU utilisé.
SBMJOB CMD(CALL PGM(LOOPS)) JOB(PRFSTDLRFL) LOG(4 0 *SECLVL) LOGCLPGM(*YES)
Métriques de Performance
Les métriques utilisées pour comparer les performances incluaient le temps CPU (UC(s)) consommé par les différents scénarios. Les niveaux d’optimisation appliqués étaient :
- SANS : Aucun niveau d’optimisation spécifique, généralement activée par défaut.
- BASIC : Optimisation de base.
- FULL : Optimisation complète, visant à maximiser la performance.
Les tests ont couvert quatre types d’exécution : l’appel
- de programme standard avec l’indicateur LR à *ON,
- de programmes sans INLR(*OFF),
- d’un programme multimodule,
- et d’un Programme utilisant une sous-procédure incluse dans un programme de Service (SRVPGM).
Résultats des Tests : Temps d’Exécution
Les résultats obtenus lors des tests sont les suivants :
Performance | Appel de programme | Programme sans INLR | Multimodules | SRVPGM |
---|---|---|---|---|
SANS optimisation | 6,155 UC(s) | 6,010 UC(s) | 0,490 UC(s) | 0,505 UC(s) |
BASIC optimisation | 5,633 UC(s) | 5,850 UC(s) | 0,341 UC(s) | 0,367 UC(s) |
FULL optimisation | 5,479 UC(s) | 5,294 UC(s) | 0,108 UC(s) | 0,147 UC(s) |
Nous pouvons noter une réelle différence entre les appels de programmes et les appels ILE par copy(programme multimodule) ou par référence(Programme de service). L’optimisation complète a réduit les temps d’exécution, en particulier pour le programme multimodule et l’utilisation d’un programme de Service.
Impact des Niveaux d’Optimisation
Les différents niveaux d’optimisation affectent le comportement du code compilé. Le niveau FULL, par exemple, se traduit par des gains de performance substantiels.
Impact de INLR sur la Performance
L’instruction INLR (*INLR = *ON
) joue un rôle dans la libération des ressources à la fin de l’exécution d’un programme RPG. En désactivant cette instruction, le programme évite la réinitialisation complète des variables et des états, ce qui peut améliorer les performances. Les tests montrent que l’optimisation FULL combinée à la suppression de *INLR peut légèrement réduire le temps CPU.
Voici les sources utilisés pour ce scénario, compilés avec la commande CRTBNDRPG afin de créer 2 programmes distincts.
- Avec *INLR à *ON
**FREE ctl-opt main(LOOPS) Dftactgrp(*no) actgrp('PERFORM'); Dcl-pr fonction extpgm('FONCTION'); rayon float(4) const; end-pr; dcl-proc LOOPS; Dcl-pi *n extpgm('LOOPS'); End-pi; dcl-s counter int(10); *inlr = *on; for counter = 1 to 10000000; fonction(6371); endfor; return; end-proc;
**FREE ctl-opt Main(diametreCercle) dftactgrp(*no) actgrp('PERFORM'); dcl-proc diametreCercle; dcl-pi *n extpgm('DIAMCERCLE'); rayon float(4) const; end-pi; dcl-s circonference float(4); *inlr = *on; circonference = 2 * 3.14159 * rayon; return; end-proc;
- Sans *INLR à *ON
**FREE ctl-opt main(LOOPS) Dftactgrp(*no) actgrp('PERFORM'); Dcl-pr diametreCercle extpgm('DIAMCERCLE'); rayon float(4) const; end-pr; dcl-proc LOOPS; Dcl-pi *n extpgm('LOOPS'); End-pi; dcl-s counter int(10); for counter = 1 to 10000000; diametreCercle(6371); endfor; return; end-proc;
**FREE ctl-opt Main(diametreCercle) dftactgrp(*no) actgrp('PERFORM'); dcl-proc diametreCercle; dcl-pi *n extpgm('DIAMCERCLE'); rayon float(4) const; end-pi; dcl-s circonference float(4); circonference = 2 * 3.14159 * rayon; return; end-proc;
Spools
Avec LR à *ON
Sans optimisation

Optimisation BASIC

Optimisation FULL

Avec *INLR à *OFF
Sans optimisation

Optimisation *BASIC

Optimisation *FULL

Programmes Multimodules et Performance
Les programmes multimodules permettent de diviser le code en plusieurs modules, ce qui améliore la modularité et peut également affecter les performances. Les tests montrent que ces programmes peuvent bénéficier d’une optimisation complète.
Dans notre cas, les 2 sources seront compilés avec CRTMODRPG pour obtenir 2 modules que nous combinerons en un seul programme avec CRTPGM.
**FREE ctl-opt main(LOOPS); Dcl-pr diametreCercle extproc('DIAMCERCLE'); rayon float(4) const; end-pr; dcl-proc LOOPS; Dcl-pi *n extpgm('LOOPS'); End-pi; dcl-s counter int(10); *inlr = *on; for counter = 1 to 10000000; diametreCercle(6371); endfor; return; end-proc;
**FREE ctl-opt nomain; dcl-proc diametreCercle export; dcl-pi *n extproc('DIAMCERCLE'); rayon float(4) const; end-pi; dcl-s circonference float(4); circonference = 2 * 3.14159 * rayon; return; end-proc;
Spools
Sans optimisation

Optimisation BASIC

Optimisation FULL

Performance des Programmes de Service (SRVPGM)
Les Programmes de Service sont une agrégation de sous-procédures qui peuvent être appelées par référence. Ces tests ont révélé que les SRVPGM optimisés offrent des performances supérieures, notamment grâce à la réduction du temps d’appel.
Le source DIAMCERCLE sera utilisé pour créer(commande CRTMODRPG) le module et celui-si sera intégré au programme de service LOOPSSRV(Commande CRTSRVPGM).
**FREE ctl-opt nomain; dcl-proc diametreCercle export; dcl-pi *n; rayon float(4) const; end-pi; dcl-s circonference float(4); circonference = 2 * 3.14159 * rayon; return; end-proc;
Le source LOOPS sera compilé pour avoir un module.
**FREE ctl-opt main(LOOPS); Dcl-pr diametreCercle; rayon float(4) const; end-pr; dcl-proc LOOPS; Dcl-pi *n extpgm('LOOPS'); End-pi; dcl-s counter int(10); *inlr = *on; for counter = 1 to 10000000; diametreCercle(6371); endfor; return; end-proc;
L’étape suivant est de créer le programme de service LOOPSSRV.
CRTSRVPGM SRVPGM(LOOPSSRV) MODULE(DIAMCERCLE) ACTGRP(*CALLER) EXPORT(*ALL) TEXT('Calcul diam cercle')
Et enfin le programme.
CRTPGM PGM(LOOPS) MODULE(LOOPS) ACTGRP(PERFORM) BNDSRVPGM(LOOPSSRV)
Spools
Sans optimisation

Optimisation BASIC

Optimisation FULL

Implications Pratiques pour les Développeurs
Les résultats de ces tests fournissent des indications précieuses pour les développeurs souhaitant optimiser leurs applications sur IBM i. En tenant compte des effets de l’INLR, en choisissant le niveau d’optimisation approprié et en des types d’appel, il est possible de réduire significativement les temps d’exécution des programmes.
Recommandations pour l’Optimisation d’IBM i
Sur la base des tests, il est recommandé d’utiliser le niveau d’optimisation FULL pour les programmes critiques, d’envisager l’utilisation de programmes multimodules ou l’usage de programme de service pour améliorer de façon significative les performances. En plus d’améliorer les performances du même ordre que les programmes multimodules, les programme de service ajoute une amélioration de la maintenabilité.
Limites de l’Étude
Bien que ces tests aient fourni des résultats utiles, ils ont été réalisés dans un environnement contrôlé et peuvent ne pas refléter toutes les conditions du monde réel. De futures études(fait par d’autres) pourraient inclure une plus grande variété de scénarios pour renforcer les conclusions.
Conclusion
L’optimisation des performances sur IBM i est une tâche complexe mais essentielle pour assurer le bon fonctionnement des applications critiques. Ces tests montrent l’importance de comprendre les effets des différentes pratiques de codage et des niveaux d’optimisation sur les performances globales du système.
Nous pouvons noter que les appels par copie(multimodules) et ceux pas référence(programme de service) amèliorent d’un rapport de 10 les performances par rapport à des appels de programmes. D’où l’intérêt de moderniser vos applications en exploitant au mieux les possibilité qu’offre Ile.
Questions Fréquemment Posées (FAQ)
- Qu’est-ce que le système IBM i ?
IBM i est une plateforme d’entreprise intégrée, connue pour sa stabilité, sa sécurité et ses capacités de traitement transactionnel. - Pourquoi les tests de performance sont-ils importants sur IBM i ?
Ils permettent d’identifier les goulots d’étranglement et d’optimiser l’utilisation des ressources, crucial pour les applications critiques. - Qu’est-ce que INLR dans RPGLE, et pourquoi affecte-t-il les performances ?
INLR est une instruction qui réinitialise les ressources à la fin d’un programme. En la supprimant, on peut améliorer très légèrement les performances en évitant des opérations de nettoyage. - Que sont les Programmes de Service dans IBM i ?
Ce sont des ensembles de sous-procédures réutilisables qui peuvent être appelés par d’autres programmes, offrant flexibilité et performances améliorées. - Comment les niveaux d’optimisation affectent-ils le code RPGLE ?
Les niveaux d’optimisation modifient la façon dont le code est compilé, influençant la vitesse d’exécution et l’efficacité des programmes. - Quels sont les avantages des programmes multimodules ?
Ils permettent une meilleure organisation du code et peuvent améliorer les performances en réduisant le temps de compilation et d’exécution.
Ressources Externes
Pour plus d’informations, consultez la documentation officielle d’IBM sur l’optimisation des performances RPGLE et d’autres ressources techniques pertinentes.
Annexes
Les sources pour tester vous-même sont sur Github, les objets sont construites grâce à BOB et Sourceorbit dans Vscode :
- 1re série de test : appel de programme avec *INLR = *ON https://github.com/ibmiiste/testsPerformance/tree/853bac04e28a38074b32d4fcd24d85a5eaff69e8
- 2me série de test : appel de programme sans *INLR = *ON https://github.com/ibmiiste/testsPerformance/tree/06858137f543ef0332820843d6d938c7c287021b
- 3me série de test : appel d’un seul et unique programme multimodule https://github.com/ibmiiste/testsPerformance/tree/6c29bc57fc6eab83204b67c049d6952e5ad22467
- 3me série de test : Programme qui appel une sous-procédure contenu dans un programme de service https://github.com/ibmiiste/testsPerformance/tree/d8a9345ef00ea6916087c802f42c5aeb6ecaf300