dimanche 23 septembre 2012

68060.library (Apollo) (V)

Encore quelques progrès intéressants sur cette librairie avec seulement des inlines, c'est à dire avec des insertions de très petites sous-routines directement dans leurs routines respectives.

Le résultat dépasse toutes mes espérances, regardez :
  
Avec en plus une superbe cerise, la librairie a rétrécie maintenant de 4692 octets.

J'ai aussi rajouté l'intégration du patch Mult64Patch : de cette façon, les utilisateurs pourront l'ôter de leur user-startup, il est inutile maintenant. D'ailleurs, ce patch est l'oeuvre du français Didier Levet (alias Kakace) qui ne donne plus signe de vie : quelqu'un sait ce qu'il devient ?
   
Ce patch intégré est très important parce qu'il est un premier pas permettant l'unification des programmes .020, .030, .040 et .060. En effet, nous avons vu au cours des années arriver plusieurs déclinaisons d'un même programme suivant le CPU installé sur les différentes machines des utilisateurs, avec donc des extensions .0x0 au bout de chaque nom !
   
Ces multiples versions étaient la cause de certaines instructions manquantes comme nous l'avons vu dans les précédents articles : par exemple, les 020 et 030 ont les "muls64" et "mulu64" intégrés dans leur coeur, alors que le 060 en est dépourvu. Puisque la majorité des programmes sont devenus codés en C/C++ à partir de la mise sur le marché des 1200 et 4000, les compilateurs correspondants pondaient des exécutables en fonction de l'option CPU indiquée par les codeurs.

Un source C/C++ utilisant des "mulu64" donnait donc un binaire différent suivant l'option -m68020 ou -m68060 précisée. Dans le premier cas, le programme obtenu utilisait directement le "mulu64" et dans l'autre une routine équivalente faite d'instructions bien présentes dans le 68060.

Les concepteurs de ces compilateurs ont utilisé cette méthode parce qu'ils savaient que les instructions manquantes émulées par la 68060.library (et par la 68040.library aussi d'ailleurs) étaient très lentes.

J'ai essayé d'expliqué simplement... Enfin bref, pour résumer c'était le bordel le plus complet...

Avec ce patch intégré, les choses changent enfin : les compilateurs n'ont maintenant qu'a appeler la fonction R_Mult64 de l'utility.library lorsqu'ils rencontrent un "mulu64" dans les sources, et ainsi les différents CPUs utiliseront automatiquement soit l'instruction en elle-même (R_Mult64 utilise un "mulu64" avec des 020 ou 030), soit la routine équivalente (le patch que je viens d'ajouter pour le 060).

De cette façon, un seul exécutable sera nécessaire quelque soit le CPU installé, ce qui simplifiera la vie des utilisateurs et permettra de bonnes performances, le tout sans bien sûr utiliser la lenteur des instructions émulées par la 68040.library ou la 68060.library.

La nouvelle version de la 68060.library v66.10 est disponible ici.
     

mercredi 19 septembre 2012

68060.library (Apollo) (IV)

Encore un nouvel article sur cette librairie ! Cette fois, les efforts et le travail sur les précédentes versions s'additionnent et la récolte des fruits bien méritée arrive enfin !

Trois fonctions spéciales 68060 qui patchent l'exec.library ont été retravaillé.

Plusieurs minuscules sous-routines ont été inliné, c'est à dire inséré directement dans la routine, donc sans "bsr/rts", ce qui accèlère légèrement le code et reduit aussi le poids final de la librairie.

Il y avait aussi du code inutilisé qui a été ôté.

Voici les benchmarks de la version originale :

Et ceux de la dernière version :

Toujours ça de gagné !

La nouvelle version de la 68060.library v66.9 est disponible ici.
    

vendredi 14 septembre 2012

68060.library (Apollo) (III)

Toujours en regardant de plus près cette 68060.library, je viens de retrouver un nouveau bug !

Et dans une fonction qui patche l'exec.library : R_CachePreDMA. Le bug est d2, il est utilisé mais pas sauvé au préalable dans la pile :

Le fix est simple, il suffit d'ôter le "move.l (a1),d2" puisque d2 est inutilisé ensuite par la routine qui pointe sur a5. De plus, (a1) contient une adresse originale d'une fonction qui va être patchée et n'a aucun intérêt à être chargée dans le datacache.

Explications : L'API d'AmigaOS 68k spécifie seulement d0-d1/a0-a1 en scratch, c'est à dire que tous les autres registres doivent impérativement être sauvés avant utilisation. Il y a quelques exceptions comme par exemple pour R_ObtainSemaphore puisque c'est autorisé par les RKM. En effet, les RKM (documentations développeurs) sont la loi, et tous les coders débutants ou experts doivent la respecter à la lettre sans discuter.

J'en ai profité pour retravailler un peu la librairie : il existe des optimisations toutes simples comme par exemple les "bsr/rts" qui se remplacent par un seul "bra" plus rapide :

Ou encore les "add.l #xx,ax" qui s'optimisent en "lea xx(ax),ax" plus courts et donc plus rapides aussi :

Il y a aussi tous les branchements bcc.l et bcc.w qui peuvent parfois être raccourcis en bcc.w et bcc.b : la librairie est maintenant plus courte de presque 3 Ko (2836 octets pour être exact).

L'auteur original n'avait pas pensé à patcher deux fonctions. En effet pour bien faire les choses, il fallait aussi patcher R_Dispatch et R_Exception qui sont des parties de R_Switch060_Fpu puisque cette dernière est une version spéciale nécessaire pour le 68060 :

Pour finir, OxyPatcher v3.14 a été testé et accélère fort bien les fonctions trigonométriques. En premier les résultats sans lui et avec ensuite :

La nouvelle version de la 68060.library v66.8 est disponible ici.
   

lundi 10 septembre 2012

68060.library (Apollo) (II)

Pour ce nouvel article, c'est une Blizzard 1260 qui a été utilisée, puisque je voulais voir les résultats obtenus avec CyberPatcher.

CyberPatcher v1.153 a été développé par Phase5, et j'ignore s'il fonctionne correctement avec les cartes accélératrices Apollo...

CyberPatcher est destiné à accélérer justement la 68060.library, en particulier les fonctions trigonométriques. Pour ce test, un quartz de 50 Mhz a été replacé sur la 1260 pour avoir la même fréquence que ma Blizzard 1230 avec un FPU bien physique 68882 à 50 Mhz aussi.

Alors bien sûr, le 030 et le 060 ne sont pas comparables : ils n'ont pas du tout la même architecture. Néanmoins, les tests suivants donneront une idée intéressante de la différence entre des sinus, cosinus et tangente logicielles et des fonctions hardware du vieux 68882 :

J'ai rajouté deux tests : UMult64 et SMult64 qui sont aussi deux instructions émulées, mais cette fois elles sont "integer", c'est à dire dans le CPU et non dans le FPU. Ces deux là sont aussi souvent utilisées par les programmes, et non présentes dans le 68060 : peut-être que Motorola n'avait plus de place pour les intégrer dans le processeur, ce qui est fort possible !

Déjà, clair que CyberPatcher accélère les fsin.x, fcos.x et ftan.x : elles sont alors environ 2,3 fois plus rapide qu'avant ! J'ignore ce que fait exactement CyberPatcher. Propose-t-il des fonctions avec d'autres algorithmes ? Pour toutes les valeurs ? Ou alors applique-t-il des astuces de programmation ?

Par contre, pas de speedup pour les UMult64 et SMult64.

En tout cas, si vous avez une carte Phase5 en 060, il est conseillé d'utiliser CyberPatcher !

Voyons ensuite la Blizzard 1230 avec son FPU à 50 Mhz :

Hum, no comment : le 68882 est environ 24 fois plus rapide sur les trois trigos, et toujours plus véloce d'environ 11 fois avec les mêmes CyberPatchés... Par contre, le 030@50 est plus lent sur les UMult64 et SMult64 !
  

vendredi 7 septembre 2012

68060.library (Apollo) (I)

En regardant de plus près la 68060.library des cartes Apollo, j'ai trouvé un bug qui a tout l'air d'être une étourderie de la part du codeur : un jsr au lieu d'un jmp ! Ce genre de bourde arrive de temps en temps, le programmeur pense jmp et tape à la va-vite jsr...

Rappel pour ceux qui ne sont pas forcement au courant des entrailles du système de l'Amiga : Motorola avait commercialisé un FPU avec le 68020, qui est une unité de calcul utilisant les nombres à virgules comme par exemple 1,5987155. En effet, le 68020 lui-même ne comprends que les nombres entiers comme 99 ou alors 1247...

Ce FPU (appelé aussi 68881 et ensuite pour une nouvelle version plus rapide 68882) est donc un composant externe au 020. Or, certainement pour réduire les coûts de fabrications et de productions, Motorola a décidé de l'intégré dans ses processeurs suivants, les 68040 et 68060. Nous faisons tous des erreurs, et là Motorola en a fait une très belle en supprimant purement et simplement toutes les fonctions trigonométriques alors qu'elles étaient bien présentes dans le 68882... Arg, si certains logarithmes ou exponentielles sont peu utilisés, les deux majeures que sont les sinus et le cosinus ne devaient surtout pas être ôtés de la sorte car elles sont souvent appelées par les programmes 3D... Regardez là par exemple dans Quake 2 :

Enfin bref, pour garder la compatibilité avec les programmes écrits pour 68020/030 et sa FPU, il a donc fallut pondre des routines de remplacement software qui émulent ces fonctions trigos maintenant manquantes dans le 68040 et le 68060. C'est ce que contient la 68040.library et la 68060.library qui se chargent par le SetPatch au démarrage de nos Amiga Classics adorés.

Or le soucis, c'est que ces fonctions software sont bien moins rapides que des fonctions hardware faites de transistors au sein même des CPUs... Désolé, mais pas bien Motorola sur ce coup là !

Pour en revenir au bug trouvé, le voici :

La routine ex_super_Fpu va être exécutée une seconde fois et plus par la R_Supervisor. La solution, c'est de remplacer le jsr par un jmp et tout va bien alors !

Cette portion de code fait partie d'une fonction de l'exec.library, la R_Switch qui devait être patchée par la 68060.library. J'en ai profité pour l'améliorer avec 70 octets de sauvés en utilisant du code de qualité ! Ca représente tout ça de gagné quand même :

La nouvelle librairie patche donc R_Switch maintenant sans le bug :

La version passe à 66.7 et fonctionne parfaitement avec RemApollo qui permet de reloger le Kickstart en fastram pour un léger speedup. Notez que la version 1.8 disponible il y a peu supporte maintenant très bien les Kickstart 3.9 pesant 1 Mo.

Pour en arriver à ce résultat, il a fallut désassembler toute la 68060.library pour recréer un source lisible, ce qui a demandé environ 16 jours de boulot acharné... Le nouveau Blog a donc un peu de retard !

La nouvelle version 66.7 est disponible en téléchargement ici.