support clients /

Comment améliorer les temps d’exécution sous SAS ?

Puis-je passer à la vitesse supérieure sous SAS ?

La réponse est OUI … mais.

Les éléments que vous trouverez dans cet article ne prouvent pas leur efficacité dans tous les cas de figure et peuvent se traduire par une consommation supérieure en ressources système.

Concernant les performances, les axes d'amélioration sont nombreux, variés et cumulatifs (méthodes de programmation, options de gestion de la mémoire, etc.).
Cet article propose des conseils complémentaires à ceux contenus dans l’article :

  • « Optimiser le temps d’exécution d’un tri sur son poste personnel » (Voir la référence en fin d’article)

Dans cet article, nous allons tout d'abord nous intéresser à l'optimisation des accès au disque dur, qui est de loin le composant le plus lent des ordinateurs actuels.
Ensuite, nous allons évoquer la possibilité d'utiliser la mémoire vive comme espace de travail SAS, le périmètre d'application, les effets sur les temps d'exécution, ainsi que les risques encourus.

Cet article est particulièrement destiné aux utilisateurs de SAS sur des monopostes munis d'une grande quantité de mémoire vive et qui exécutent de nombreux traitements SAS, sur des volumes de données modérés à élevés.

Note : Veuillez au préalable positionner l’option sortsize à « MAX » dans le fichier SASV9.CFG (situé dans le répertoire d’installation de SAS) ou en début de programme SAS.

1. L'optimisation des accès disque grâce à l'option SGIO

Par défaut cette option n'est pas activée dans SAS sous Windows.

Si vous disposez de plus d'1Go de mémoire vive (RAM) sur votre ordinateur et qu'il est destiné essentiellement SAS, alors vous pouvez positionner l'option SGIO dans SAS.

Cette option permet d'éviter d'utiliser les mémoires tampon entre la RAM et le disque dur.
Son efficacité est significative notamment lors d'écritures séquentielles (création de tables volumineuses par exemple ou tris), cependant, elle nécessite un peu plus de RAM disponible et de puissance processeur que le réglage d'origine (quelques pourcentages).

Son utilisation est à conjuguer avec l’option BUFNO, qui est le nombre de mémoires tampons (« buffers ») utilisés par SAS, qui par défaut est égale à 1.
Cette option permet de mettre en valeur l'efficacité de l'option SGIO.

L'option BUFNO est donc le paramètre à faire varier pour tenter de déterminer la valeur optimale correspondant à votre système.

Le test qui suit est composé d'un programme SAS (en fin d'article), qui crée des tables SAS d'1 million de lignes, avec 20 variables de 32 caractères au contenu aléatoire, de taille égale à 625Mo chacune.

Comment modifier les options ?

Dans le fichier SASV9.CFG (par exemple : C:\Program Files\SAS\SASFoundation\9.2\nls\fr\SASV9.CFG)

Options à saisir :
   -sgio
   -bufno X

X est la valeur que nous faisons varier.
Note : L’option Bufno peut être positionnée en option dans chaque étape Data ou « procédure » au lieu d’être un paramètre général à SAS lorsqu’il est positionné dans le fichier SASV9.CFG.

Pour prendre en compte la modification, il faut enregistrer ce fichier puis relancer SAS.

  A/ Création de tables

Sans utiliser d'option particulière sous SAS, en réalisant 10 créations de tables par la même méthode, voici les temps moyens obtenus par création de table lors de l'exécution du programme en annexe.

Par défaut :

SAS par Défaut
Test1
Test2
Test3
moyenne (en s) par table
34,36
27,57
26,779

Les tests 1, 2 et 3 sont identiques. Ils consistent en la création de 10 tables SAS identiques à l'aide du programme en fin d'article.

En activant à présent l'option SGIO, voici les résultats en fonction de la variation du paramètre BUFNO.

Résultats :

 SGIO

Bufno = 1

bufno = 2

bufno = 4

bufno = 16

bufno = 32

bufno = 64

bufno = 1024

Moy

44,687

39,424

31,202

24,155

23,898

30,216

28,84

Les valeurs obtenues sont fluctuantes et dépendantes des autres programmes accédant au disque dur de l'ordinateur.

Nous pouvons conclure que l'option SGIO permet d'obtenir de meilleurs résultats sur les temps d'écriture des tables SAS, combinée à une valeur de BUFNO adaptée.
Un mauvais paramétrage de BUFNO aura même une conséquence négative sur les temps de traitement !

Ci-dessous la courbe représentative des meilleures courbes entre SAS par défaut, et SGIO conjuguée à BUFNO :

Sans l'option SGIO, le temps d'exécution du même traitement oscille fortement.
Avec un paramétrage inadapté de SGIO (bufno insuffisant ou trop élevé), le temps de traitement peut augmenter par rapport au paramétrage par défaut !!
Un équilibre est à identifier en fonction de l'opération demandée afin d'obtenir les meilleures performances ainsi que le maximum de régularité.

B/ Tris de tables

Un certain nombre de procédures SAS nécessitent en pré requis que les tables soient triées.
L’article « Optimiser le temps d’exécution d’un tri sur son poste personnel » permet de paramétrer SAS pour améliorer significativement les temps de tris.

L'option SGIO (combinée avec BUFNO) apporte une amélioration supplémentaire, car elle permet d'accélérer l'accès physique aux données.

La courbe ci-dessous montre le temps d'exécution sur 10 tris de tables de 625Mo

  • SAS® 9.2 par défaut (vert)
  • SAS® 9.2 + SGIO + BUFNO=32 (rouge)

Le gain maximal entre les deux meilleurs tris est de 8,63s et les opérations de tri sont toujours plus rapides avec l'option SGIO (+ BUFNO=32)

En comparant les meilleures moyennes :

  • Par défaut : 35,2s par table
  • SGIO : 28,46s par table soit un gain espéré de plus de 19%


La suite de cet article est destinée à des utilisations spécifiques de SAS, notamment dans un contexte mono-utilisateur et sur un poste équipé d'une grande quantité de RAM.

Les gains de performances atteignables peuvent s'avérer très importants, mais cela implique une approche différente dans la programmation SAS et le respect de certaines précautions.

2. Créer des tables de taille moyenne dans une « memlib »

Pour pouvoir créer une bibliothèque SAS directement en mémoire plutôt que sur disque, il faut modifier au préalable une stratégie de sécurité dans Windows, et permettre le verrouillage de pages mémoire :

Menu Démarrer > Panneau de configuration > Outils d'Administration > Stratégies de sécurité locale > Verrouiller des pages en mémoire.

Double-cliquer sur cette stratégie et y ajouter votre compte Windows.
Si vous n'êtes pas administrateur de votre poste, cette opération devra être réalisée par l'administrateur système.
Cette fonctionnalité permet de réserver une zone mémoire, d'une taille définie et nécessairement inférieure à la taille mémoire disponible sur votre ordinateur.

Cette bibliothèque « virtuelle » est par essence volatile, donc toutes les données contenues dans cette bibliothèque doivent être stockées sur disque en fin de traitement, sinon, elles sont perdues dans les cas suivants :

  • à l'arrêt de SAS
  • à l'arrêt de votre ordinateur.

Notez que la réinitialisation du libname (libname test  clear ;) ne supprime pas les objets de cette bibliothèque, et ne libère donc pas la mémoire vive utilisée !
Il faudra vider les tables de la bibliothèque par la commande suivante pour libérer effectivement la mémoire :

proc datasets lib=test;
delete table1 table2;
run;
 

SAS considère cette bibliothèque comme un mini disque dur, ce qui signifie que le volume cumulé des données gérées dans cette « memlib » ne doit jamais atteindre la taille allouée.

Dans la pratique, comment activer la fonction dans SAS ?

Il suffit de positionner le mot clé « memlib » dans la définition de votre libname :

libname test "C:\temp" memlib; 

SAS va considérer que les données crées dans la bibliothèque “test” sont stockées dans "C:\temp" alors qu’elles sont stockées en mémoire !

Pour pouvoir contrôler la taille maximale réservée aux memlibs, il faut positionner l'option

-MEMMAXSZ xxxxM

Dans le fichier SASV9.CFG (par exemple : C:\Program Files\SAS\SASFoundation\9.2\nls\fr\SASV9.CFG)

Par exemple :

-MEMMAXSZ 1024M

Si vous disposez de + de 1024M de RAM disponible.
 
Si le volume cumulé des tables SAS nécessite davantage de mémoire et que vous atteignez la limite imposée, le traitement SAS en cours sera interrompu avec un message d'erreur indiquant que l'espace disque maximal a été atteint et que le fichier concerné est soit corrompu soit incomplet.

Il est important de noter que l'utilisation des memlibs ne conduira pas à un blocage du système d'exploitation faute de mémoire disponible.

Cependant, vous ne pourrez constater une meilleure performance que si vous optez pour un placement de la SASWORK également en RAM.

Sinon, vos tables seront en mémoire, leur accès sera extrêmement rapide, mais toute opération sous SAS (tri, procédure stat…) nécessitera la création de données temporaires en « WORK », par définition, stockée sur disque dur, ce qui fera perdre tout le bénéfice de l’utilisation de la mémoire.

3. Si vous maitrisez la volumétrie (données utiles, espace temporaire), vous pouvez positionner également la « WORK » dans une memlib.

Si vous êtes dans les cas suivants, alors les meilleurs résultats pourront être atteints :

  • le volume cumulé de vos tables de données est faible ou modéré
  • vous avez beaucoup de RAM disponible (minimum 1Go)
  • vous faites des tris ou des analyses de données sur des petites tables (jusqu'à 200-300Mo)

Alors, vous pourrez également positionner la SASWORK en « memlib »  grâce à l’option

-MEMLIB

Dans le fichier SASV9.CFG (par exemple : C:\Program Files\SAS\SASFoundation\9.2\nls\fr\SASV9.CFG)

Il est important de savoir, que vu la taille mémoire qui doit être allouée :

  • Au stockage « temporaire » des données opérationnelles
  • A la mémoire de travail de SAS
  • Au stockage temporaire des données de travail sous SAS (work)

Et les ressources mémoires étant limitées, vous ne pourrez donc ni travailler sur des tables volumineuses, ni laisser en mémoire ou dans les memlib des tables de données qui ne sont plus utilisées.

Il faut donc tenir compte de ces spécificités dans votre programmation sous SAS et supprimer dès que possible les tables de la WORK qui ne sont plus utilisées.
Une fois les modifications faites sur les tables stockées en memlib, vous pouvez les placer dans une bibliothèque SAS physique.

Cette programmation est contraignante, mais les gains de performances peuvent être spectaculaires.

Voici un tableau récapitulatif du temps de création et de tri d'une table d'1 million de lignes, avec 20 variables de 32 caractères au contenu aléatoire, de taille égale à 625Mo

La bibliothèque Test et SASWORK sont en « memlib », il n’y a donc aucune entrée-sortie (I/O) sur disque dur.

L’exemple suivant montre la logique à mettre en œuvre pour gagner 30% de temps sur le même traitement, malgré une programmation SAS plus contraignante :

Créer une table SAS (programme ci-dessous) et la trier sur 3 variables.

SAS Optimisé

SAS par defaut

libname test "c:\temp" memlib ;
options sortsize="max";

%macro createtable(lib,nom,var,n,v,m,l);
data &lib..&nom(drop=i);
do i=1 to &n;
%do i=1%to &v;
&var&i=put(md5(int(ranuni(1)*&m)),hex&l..);
%end;
output;
end;
run;
%mend;

/* création de la table en RAM */

% createtable (test,bigdata01,var,1000000,20,5000,32);

/* tri de la table en RAM */

proc sort data=test.bigdata01;
by var1 var2 var3;
run;

/* copie finale sur disque */

libname dur "c:\temp\stockage";
data dur.bigdata01;
set test.bigdata01;
run;

libname dur "c:\temp";
options sortsize="max";

%macro createtable(lib,nom,var,n,v,m,l);
data &lib..&nom(drop=i);
do i=1 to &n;
%do i=1%to &v;
&var&i=put(md5(int(ranuni(1)*&m)),hex&l..);
%end;
output;
end;
run;
%mend;

/* création de la table sur disque dur */

% createtable (dur,bigdata01,var,1000000,20,5000,32);

/* tri de la table sur disque dur */

proc sort data=dur.bigdata01;
by var1 var2 var3;
run;

Temps : 9,68 + 2,32 + 20,16 = 32,16s

Temps : 22,38 + 23,73 = 46,11s

 

Soit +30,25% pour réaliser les mêmes opérations !

Conclusion 

Selon les étapes que vous souhaitez réaliser, le volume de vos données et la quantité de mémoire vive de votre ordinateur, vous pouvez combiner les différentes procédures pour tenter d'améliorer les performances de vos programmes SAS.
Parfois le tuning peut s'avérer pénalisant en termes de performances sur certaines opérations, mais très avantageux sur d'autres.
Vous seul(e) pouvez identifier le meilleur paramétrage en fonction de vos programmes et vos données.

Références 

Article sur l’optimisation des tris sous SAS :
http://www.sas.com/offices/europe/france/services/support/articles/US200702_a3.html

Documentation SAS traitant des performances :
http://support.sas.com/onlinedoc/913/getDoc/en/hostwin.hlp/perform.htm

Pour aller plus loin, l’utilisation de SASFILE permet de placer une seule table SAS en mémoire :
http://support.sas.com/onlinedoc/913/getDoc/en/lrdict.hlp/a001500739.htm

Programmes SAS utilisés pour réaliser les tests dans le cadre de cet article :

/* Positionner le sortsize à MAX pour pouvoir optimiser le temps de tri*/
options sortsize="max";

libname test "C:\temp\";

/*Programme de création de table volumineuse */

%macro createtable(lib,nom,var,n,v,m,l);
/*lib=bibliothèque en sortie
nom=nom de la table
var=préfixe du nom de variable
n=nombre d'observations
v=nombre de variables
m=nombre de modalités possibles
l=longueur de la chaine de caractères
*/

data &lib..&nom(drop=i);
do i=1 to &n;
%do i=1 %to &v;
&var&i=put(md5(int(ranuni(1)*&m)),hex&l..);
%end;
output;
end;
run;
%mend;

/*Appel de la macro pour créer dans la bibliothèque TEST des tables d'un million d'observations, de 20 variables de longueur 32 ayant 5000 modalités*/
%createtable(test,bigdata01,var,1000000,20,5000,32);
%createtable(test,bigdata02,var,1000000,20,5000,32);
%createtable(test,bigdata03,var,1000000,20,5000,32);
%createtable(test,bigdata04,var,1000000,20,5000,32);
%createtable(test,bigdata05,var,1000000,20,5000,32);
%createtable(test,bigdata06,var,1000000,20,5000,32);
%createtable(test,bigdata07,var,1000000,20,5000,32);
%createtable(test,bigdata08,var,1000000,20,5000,32);
%createtable(test,bigdata09,var,1000000,20,5000,32);
%createtable(test,bigdata10,var,1000000,20,5000,32);

Marc Avezac
Consultant Support Clients SAS France