2005-06-04

Plus de PowerPC chez Apple ?

Je n'ai pas écrit depuis longtemps, mais aujourd'hui j'ai lu une annonce en phase avec mes deux précédents billets.

Vu chez CNet (ou « C|Net », ils aiment bien les pipes), un article annonçant qu'Apple passerait à des puces Intel. Je me demande ce qui leur prend chez Pomme. Je vérifie la date... non, le 1er avril est passé depuis deux mois.

J'ai toujours préféré la famille des processeurs PowerPC vis-à-vis des processeurs de chez Intel. Ok, le nom « PowerPC » est super naze, ça fait penser au « PC » alors que ça n'a rien à voir. C'est peut-être la raison pour laquelle Apple utilise les termes « G3 », « G4 », « G5 »... Non, ce qui me fait aimer le PPC (voilà, en contracté ça sonne déjà mieux) c'est son architecture qui correspond davantage à ce que j'attends en tant que développeur : modernité, simplicité, rationnalité, confort... C'est donc avec tristesse que je prendrai cette nouvelle si elle s'avère. On verra bien lundi.

Heureusement qu'entre temps, le PPC s'est trouvé des clients de poids du côté des consoles de jeux : Microsoft, Sony, Nintendo, William Saurin... ça va équilibrer la balance. Mais je regrette quand même qu'on se retrouve avec une uniformisation du matériel. L'intéropérabilité, oui ; l'uniformisation, non.

Ça va encore avoir un effet pervers du côté de certains développeurs qui ne verront l'informatique que par le petit bout de la lorgnette, assimilant les choix architecturaux des ingénieurs d'Intel à la norme en matière de processeurs.

L'illustration la plus fragrante est le rangement des octets en mémoire. Prenons un nombre de 32 bits dont la valeur est 12345678, soit 4 octets : 12 34 56 78. Un processeur PowerPC stockera ce nombre dans cet ordre là, dans la mémoire central, ou dans ses registres de travail.

Un processeur Intel stockera ce nombre en mémoire sous la forme 78 56 34 12. Autant dire que c'est la plaie pour débuguer. À chaque fois que l'on analyse la mémoire pour comprendre ce qui s'y passe, on est sans cesse en train d'effectuer une gymnastique mentale.

Il faut aussi savoir qu'une fois dans un registre de travail, la valeur retrouve sa forme d'origine : 12 34 56 78. Ça revient à ne pas oublier que c'est la valse des octets entre le processeur et la mémoire ; cela implique aussi de bien comprendre comment le compilateur traduira le code que l'on a écrit.

Voici un exemple de cette gymnastique que l'on fait quand on écrit du code C++ :

On vient de décoder une image PNG 32 bits. Chaque pixel fait 32 bits, et en mémoire on a une suite de pixels : RVBA RVBA RVBA RVBA RVBA... soit 8 bits pour le Rouge, 8 bits pour le Vert, 8 bits pour le Bleu, et 8 bits pour l'Alpha (Opacité).

Pour un traitement efficace, on traite chaque pixel comme un nombre de 32 bits.

// Extrait le premier pixel de l'image. pBuffer pointe sur les pixels de l'image.
uint32 pixel = pBuffer[0];

// On peut considérer la variable « pixel » comme un registre de travail du processeur.
// On a en effet une idée de la façon dont sera compilé ce bout de code.

Mettons qu'on souhaite isoler les quatre composantes qui forment notre pixel RVBA. Avec un processeur Intel, le pixel a subi une inversion :

// Le pixel, stocké dans un registre, est désormais sous la forme ABVR
uint32 r = (pixel >> 0) & 0x000000ff;  // ABVR -> ABVR -> 000R (Rouge)
uint32 v = (pixel >> 8) & 0x000000ff;  // ABVR -> 0ABV -> 000V (Vert)
uint32 b = (pixel >> 16) & 0x000000ff; // ABVR -> 00AB -> 000B (Bleu)
uint32 a = (pixel >> 24) & 0x000000ff; // ABVR -> 000A -> 000A (Alpha)

(Là, j'ai perdu 12 lecteurs)

Sur un processeur qui n'effectue pas cette inversion de façon naturelle, comme le PowerPC, on reste dans une utilisation cohérente entre la représentation mémoire et le registre de travail. Voici le code correspondant :

// On maintient une valeur de la forme RVBA.
uint32 r = (pixel >> 24) & 0x000000ff; // RVBA -> 000R -> 000R (Rouge)
uint32 v = (pixel >> 16) & 0x000000ff; // RVBA -> 00RV -> 000V (Vert)
uint32 b = (pixel >> 8) & 0x000000ff;  // RVBA -> 0RVB -> 000B (Bleu)
uint32 a = (pixel >> 0) & 0x000000ff;  // RVBA -> RVBA -> 000A (Alpha)

(Whaaa, vous êtes encore là ? :))

Notez que du coup, il est nécessaire de faire deux versions du code, sous peine d'avoir un programme non portable d'une architecture à l'autre. En n'ayant plus que des processeurs travaillant comme le font les processeurs Intel, cela laissera penser à des développeurs qu'il s'agit là de la façon naturelle de gérer des valeurs au sein d'un ordinateur, alors qu'il s'agit de la méthode la plus contraignante des deux, un choix technologique qu'on traine comme un boulet depuis des dizaines d'années. Vi, j'en connais que ça ne gène absolument pas car ils n'ont connu que ça.

Au delà de l'aspect technique, il y a aussi l'aspect « expérience utilisateur » qui risque d'en prendre un coup. L'avantage du Mac, c'est justement cette architecture matérielle donnée qui donne la garantie d'un bon fonctionnement. Là, avec un marché Mac à deux types de processeurs, cela va obliger les créateurs de logiciels à deux fois plus de travail, ça coutera cher, et les risques de bugs seront accrus (maitriser deux architectures ce n'est pas du gâteaux). Ou alors on fait du code tout bidon : adieu donc au code optimisé qui fait le bonheur des utilisateurs (Altivec notamment, miam).

Bref, tout ça pour dire que ça me déplairait grandement de voir des Mac tourner sur du Intel. On perdra en diversité, on perdra en connaissance, on perdra en expérience utilisateur. Et de mon côté, je ne recommanderai plus le Mac aussi chaudement que maintenant. Si c'est pour avoir un processeur Intel, autant acheter un PC. Dans le 12e à Paris y'a tout ce qu'il faut niveau boutique... « ni repris ni échangé ni remboursé ; on n'accepte pas les chèques » :)