Ma passion pour l'assembleur
... et l'électronique
 Benoît Vogt

La programmation

Passionné par la programmation, j'ai commencé comme tout le monde avec une calculette et ses quelques dizaines de pas. Tout a démarré avec le Mastermind. Ce qui m'a plu : 

- Optimiser le programme pour qu'il "rentre" dans la mémoire de la calculette. 
- Pas d'y jouer.

Et c'est toujours mon même but aujourd'hui : la performance.

La programmation est pour moi scindée en deux phases : 
- Premièrement réfléchir sur un papier pour concevoir astucieusement et optimiser, 
- Puis transcrire le programme en langage approprié. Approprié est le bon mot.


Mais quel langage choisir ? Et pour quoi faire ?







Le langage Basic est très simple et pratique. C'est le langage du Wordbasic pour les macros, par exemple. Mettre en page une ordonnance avec une macro est très utile et rapide avec le Basic. 
Mais plus un langage parait simple (évolué) et plus il y a d'intermédiaire entre l'instruction et le microprocesseur. Et ces intermédiaires prennent du temps.
Le Basic est donc pratique pour des traitements simples mais devient impossible en cas de calculs sur des grands nombres ou des recherches dans de grands fichiers.
 


FOR n = 0 TO 1000000
NEXT
Langage Basic : Boucle à vide d'un million prenant une bonne seconde.

Il est alors logique de chercher un autre langage plus rapide quand le Basic ne sera pas performant. Le langage C répond bien à la question pour une grande base de donnée. Mais plus le fichier dans lequel on recherche la chaîne est grand et plus les secondes augmentent et cela d'autant plus qu'il existe "une connexion réseau" entre le client et le serveur.
 


for (n=0;n<1000000;n++);
Langage C++ : Boucle à vide d'un million (immédiat).

Il ne reste plus qu'à s'adresser directement au microprocesseur et à ses registres. C'est l'Assembleur. Et avec ce langage, je suis devenu parfaitement satisfait pour les bases de données et les calculs rapides. 

Puis je suis devenu passionné par la simplicité et la rigueur de ce langage, j'ai utilisé sa puissance pour résoudre des arborescences longues où une vie ne suffirait pas à effectuer des milliards de tests.

Bien sûr l'assembleur semble plus difficile au premier abord. Mais il est finalement simple à condition de lui accorder beaucoup de temps et de rigueur. Il prend souvent plus de lignes mais pas toujours. La rotation d'un bit est par exemple plus simple en assembleur qu'en C.
 


    mov ecx, 1000000
boucle1:
    dec ecx
    cmp ecx, 0
    jb boucle1
Langage Assembleur : Boucle à vide d'un million (immédiat).

L'écriture d'un programme en Assembleur exclusif est vraiment ingrate car il faut tout déclarer et contrôler. Mais cela n'est maintenant plus très utile.

Il est plus astucieux d'utiliser une interface C visuelle (CBuilder, par exemple) et d'y incorporer des routines Assembleur (ASM) qui ne s'occuperont que des calculs répétitifs nécessitant toute la puissance de l'Assembleur.
 

Pour illustrer le choix du langage, le programme suivant est en CBuilder. L'exemple ci-dessous est un extrait de Basucli permettant de contrôler la bonne surveillance des patients opérés de cancers. Il est plus simple et rapide d'utiliser le C++ dans ce cas où la performance est moins importante. 
Mais dans Basucli comme dans Basuro, la gestion des chaînes de fichiers est bien sûr écrite en Assembleur car le C est moins performant dans ce domaine.
 

... 
    for (n=0;n<taillefic/400;n++)
        {
        indbar++;
        Form1->ProgressBar1->Position = indbar;

        fread(buf, 400, 1, stream);
        Form1->Labelws->Caption=buf;
        Form1->Labelw1->Caption=Form1->Labelws->Caption.SubString(1+1+5+1+3,10);
        Form1->DTW->Date=StrToDate(Form1->Labelw1->Caption);
        j=Form1->DTW->Date;

        nk=StrToInt(Form1->Labelws->Caption.SubString(1+1+5,1));

            Form1->Labelw1->Caption="libonco.txt";
            LinesInput();

            for (p=tab[nk][0];p<tab[nk][1];p++)
            {
            if (Form1->ListBoxw1->Items->Strings[p].SubString(1+4,1)==".")
                {
                //recherche 'mois' ou 'an'  dans " 6 mois" ou "xx&~.PSA 2 ans" 
                Form1->Labelw1->Caption=Form1->ListBoxw1->Items->Strings[p];
                q=0;
                q=AnsiPos("mois",Form1->Labelw1->Caption);
                if (q!=0)
                    {
Form1->Labelw2->Caption=Trim(Form1->Labelw1->Caption.SubString(1+q-4,2)); 

...

 Form1->SGR2->Cells[0][trouve]="";
 Form1->Labelw1->Caption="basucli.dat";
 Form1->Labelw2->Caption=407; //sizenom
 Form1->Labelw3->Caption=231; //offset0
 Form1->Labelw4->Caption=Form1->SGR2->Cells[1][trouve]; //code=ND
 Form1->Labelw5->Caption=""; //offsetDate
 Form1->Labelw6->Caption=""; //Date1
 Form1->Labelw7->Caption=""; //Date2
 Form1->Labelw8->Caption="11"; //Directives
 RechercheV();
 if (Form1->Labelw2->Caption==0) goto saute;
 Form1->SGR2->Cells[0][trouve] = Form1->Labelw1->Caption.SubString(1+1,23);
saute:
 Form1->SGR2->RowCount = trouve+1;

                }   //if
suite:
            }   //for p
        }   //for n
...
 

Langage C++: Extrait de Basucli. La fonction "Caption.SubString()" est très évoluée et facile d'emploi mais est bien plus longue que la même routine écrite en assembleur. Son emploi dans ce cas allonge un peu l'exécution. En revanche, le programme fait appel à "RechercheV()" qui est une routine écrite en Assembleur et intégrée dans le programme. Elle est grandement plus performante que le C pour rechercher le code ND dans le fichier basucli.dat;

 

Pour illustrer le choix du langage, le programme suivant est en assembleur exclusif pour les calculs et l'affichage graphique est en CBuilder. L'exemple ci-dessous est un extrait d'une routine assembleur intégrée dans le programme P45 résolvant le jeu de réflexion Pentamino en 2D et 3D. Dans cet exemple, la forme 3D 3x4x5 livre 3940 solutions différentes et des milliards de tests sont nécessaires suivant les formes explorées. 

Dans ce programme, la partie réflexion-méthodologie de l'arborescence est capitale et c'est la plus intéressante. C'est sa performance qui est la récompense et l'assembleur ne déçoit pas.
 
 

...
    mov ebx, 0
    mov ecx, 0
TestTabO:
    lea esi, tabo
    add esi, ecx
    lodsd
    xchg ah, al
    ror eax, 16
    xchg ah, al
    mov al, 0
    ror eax, 8
    cmp edx, eax
    je CaseExiste
    inc ebx
    add ecx, 3
    cmp ebx, nbcase
    jb TestTabO
    jmp HorsCase
CaseExiste:
    //et test libre dans tabr et met 1
    cmp tabr[ebx], 0
    jne HorsCase
    mov tabr[ebx], 1

 cmp tab1[edi+4], -1     //obligé car -1=0FFFFFFFFh >
    je testneg
    mov eax, tab1[edi+4]
    mov esi, edi
    add esi, 4
    add edi, 4
    cmp edi, ntot4m
    je finliste
    jmp testsuiv
...

Langage Assembleur : Extrait de P45 dénombrant les solutions du Pentamino

Effectivement, cette succession de lignes peut décourager. Mais ce programme P45 permet de trouver et enregistrer en PCX ces 3940 solutions en 17h. Il y est effectué 196 milliards de tests. Un humain ne peut pas tester la position de 3,2 millions de pièces chaque seconde. L'ordinateur montre alors toute sa performance et l'humain ne peut pas le concurrencer. Mais l'ordinateur n'invente rien et ne créé rien. Il exécute le programme que je lui communique. L'intelligence et la création, c'est l'humain et aucune machine ne peut la reproduire. 

On peut bien sûr accélérer cette procédure mais dans le cas présent, il n'y a délibérément aucun algorithme. L'arborescence est complète, bête et totale et prend du temps. L'avantage est de ne rien oublier. Un algorithme peut oublier un test par erreur. Gagner du temps, c'est aussi risquer d'oublier une arborescence et de se tromper. 

Pour le 2D et par exemple pour le rectangle 6x10, le temps d'exécution est de 1'30" avec 291 millions de tests pour trouver 2339 solutions différentes. L'écriture des 2339x4 solutions avec symétries dans un fichier prend du temps (Open, Handle, Write, Close). Ce temps est de l'ordre de 10 ms par accès. Il faut donc 1'30" de plus pour inscrire les solutions. Mais pour le 3D, le nombre de tests est plus considérable. Il faut 17h de calcul et seulement 7 minutes pour inscrire la liste des 31520 solutions (avec les symétries). 

Pour le 2D, il faudrait effacer le temps d'accès aux données et donc utiliser un microcontrôleur qui soit à la fois un microprocesseur et une mémoire vive qui reste vivante lorsque l'ordinateur est éteint. Le passage des data se ferait intimement entre registres et mémoire sans délai. Ce composant est en étude, il s'agit du "Memristor". 

Mais pour le 3D, c'est la vitesse de calcul qui prime. Les qubits (bits quantiques) prennent ici toute leur importance avec des calculs en parallèle et non plus en série et une puissance exponentielle liée au nombre de qubits employées. Même si finalement, l'émulation des qubits en bits prendra un peu de temps pour le stockage, ces nouvelles approches sont prometteuses.
 

P45 en C et en Assembleur : Pentamino 3x4x5, une des 3940 solutions

 

L'électronique

Certains se détendent en lisant Sartre. Moi, c'est la physique classique et quantique. 

En particulier, l'électronique a envahie notre vie depuis la découverte du génial transistor semi-conducteur. Elle nous rend service et est finalement accessible à tout le monde si on essaye de comprendre. 

La compréhension et l'utilisation du composants et la programmation des microcontroleurs offrent des possibilités fabuleuses et permettent de réaliser des idées originales dans le domaine de la santé ou de notre confort.

Je suis passionné par cette science.

 

Accueil du site