Les dépendances

Bonjour,

Je suis tomber sur cet article:

http://thebacklog.net/2011/04/04/a-nice-picture-of-dependency-hell/

Voila la visualisation des dépendances des logiciels et libs:

gentoo graphic dependency hell

Il y as des dépendances dans tout les sens, mais le pire c’est les dépendances circulaires, il vous faut A pour avoir B, mais B pour avoir A… et donc comment vous faite depuis 0? Vous mettez un A compilé trouvé sur internet, vous compilez B, puis compilez A et écrasez le A de internet.

En 5 ans le nombres de packets à augmenté, les dépendances se sont complexifié. Cela rends la maintenance d’un OS plus compliqué. Faire l’arbre de dépendances pour calculer les dépendances à installer avant le packet deviens de plus en plus complexe.

Un logiciel peu vouloir une lib en version 1.2 et pas moins ni plus, et un autre utilise cette libs en version 1.3 minimum.

Vous développeur, que pouvez vous faire?

A votre niveau, que pouvez vous faire? Voila une serie de conseille qui sont à appliquer avec intelligence, et non comme des régles strictes:

  • Minimiser le nombre de dépendances: Cela permet de rendre la compilation plus facile pour les contributeurs potentiels. D’avoir moins besoin d’adapter votre logiciel pour les changements d’API des libs que vous utilisez. Augmente les performances de votre logiciel (1 relocation en moins, peu être critique quand vous l’appelez comme un fou dans une boucle) et permet à votre compilateur le LTO et/ou d’inline la fonction qui vas bien et d’utiliser moins de mémoire. Permet de minimiser la taille en supprimant tout les codes compilé peu/pas utilisé. Cela permet de minimiser les failles en minimisant le code chargé et donc le nombre de faille potentiel. Comment? En analysant les choses que vous n’utilisez pas: Certain lie des libs sans même utiliser la moindre functions. Si vous utilisez très peu de function d’une libs, il est souvent plus intéressants de refaire ces functions dans votre programme (sauf si vous ne voulais pas avoir à charge leur maintenance: par exemple les functions de hash de openssl qui sont actualisé pour exploiter au mieux les instructions du cpu)
  • Etre tolérant sur les versions de libs supporté: Cela permet de ne pas rentré en conflit avec d’autre logiciel demandant une version supérieur ou inférieur d’une lib. Comment? En ne pas se jetant sur la dernière fonctionnalité de vos libs (mais utiliser la si c’est un avantage majeur: J’utilise dans Ultracopier Qt 4.4 pour la détection de l’espace libre, impossible de faire autrement sans rajouter une dépendance problématique)
  • Pour le packaging sous Windows, vous pouvez utiliser une copie privée de vos dll, et donc avoir des versions spécifique sans que cela rentre en conflit avec les autres logiciels. Cela n’est pas applicable au OS qui mettent en commun les lib et qui ont une gestion de packets.

Si vous faite une lib

Si vous faite une lib, voila les conseilles:

  • Dépendance: évitez de mettre en dépendance une libs qui directement ou non dépende de votre libs.
  • Versioning et API: Exploser une API stable, que vous aller changer un minimum de fois en cumulant les changements. Mettez un numéro de version, avec un nombre majeur caractérisant un changement d’API, et un nombre mineur pour les changements interne qui ne change pas l’API.

Voila, en espérant vous avoir éclairé.

Load balancing et scalabilité avec CatchChallenger

Bonjour,

Je rentre dans une phase de testing, benchmarking et stabilisation dans CatchChallenger. Je n’est pas encore fait l’optimisation, juste respecter les régles de codage.

Les temps noyau, et gestion de matériel dans le cas du raspberry pi sont bien supérieur aux temps en espace utilisateur. Donc un load balancer prendrais autant de charge CPU que l’application en elle même. Le seul cas réel d’un load balancer serai un gros load balancer et de toute petite nodes. Mais dans tout les cas le load balancer ne pourra jamais gérer plus de client que les nodes elle même.

Pourquoi un load balancer?

Pour la haute disponibilité: Il suffit de faire soit un/des haproxy en mode tcp, ou faire cela via DNS (ce qui permet de faire des personnalisation par pays pour optimiser le trafic, et cela est parfaitement scalable)

Répartition de charge: impossible via un logiciel si les serveurs sont symétrique, car il passerai plus de temps cpu a répartir la charge que à travailler (induirai des latences et sous chargerai les serveurs). Pour les serveurs logins, la gestion par pays des DNS permet cela.

 

Et pour les games serveurs? Pour la haute disponibilité: Pas besoin, le serveur est down, les joueurs peuvent aller jouer sur un autre serveur similaire. Répartition de charge: Les limites par serveur force les joueurs a se répartir sur les différents serveurs, sans compter avec le faire qu’il vont sur les serveurs les plus proches de chez eux.

 

Un raspberry pi 1, ARMv6 à 700Mhz tiens une charge de 60000 joueurs. Ceux sans optimisation. Pour que une attaque DDOS soit intéressante il faut que le prix de l’attaque soit bien inférieur au prix du préjudice. Comme ici le botnet pour attaquer CatchChallenger doit être vraiment três grands face aux peu de serveur pour surporter un tel charge, la possibilité d’une attaque DDOS est relativement faible.

Attention: Les options du serveurs ont une forte influence sur la monté en charge et le confort des utilisateurs.

Map infini

Les maps infini sont théoriquement supporté (infini à la minecraft: trop grande humainement pour être explorer). La gestion et mise a l’échelle as été fortement amélioré. Il deviens donc envisageable de faire les maps par génération procédurale.

Raspberry pi 3

Je ne vous conseille pas le raspberry pi 3 car pour le même prix vous avez the le Odroid C2 qui vous offres: une bien meilleure carte graphique, une mémoire bien plus rapide, plus grande, un meilleur bus de communication entre les composants, une carte réseau meilleure et mieux interfacé (pas via l’usb), l’eMMC, …

 

N’hésité pas a acheter les logiciels qui vous ont plus ou apporté quelque chose (CatchChallenger).

Bye,

Cpu buffer vs cache

Bonjour,

Sur une section de code sensible je me suis demander, ce qui est mieux (teste fait en C++):

int a;
while(10000000x)
a=10;

Ou:

int a;
while(10000000x)
if(a!=10)
a=10;

Avec la 1ère partie, une vague d’information qui viens du coeur du cpu viens remplir les différents buffer (L1, L2, L3) jusqu’as la mémoire centrale de manière non bloquante. Ce qui provoque une grosse consommation sur tout le chemin de l’information. Cela est plus performant sur ARMv6 in-order surchargé car cela est non bloquant (2x), mais plus lent de 30% sur un x86 vide.

La 2ème partie est plus lente sur un système surchargé car le CPU passe sont temps a remettre en cache l’information à cause des changements de contexte qui purge les différents cache. Bien sur cette solution est préférable si cela permet d’évité un traitement lourd, mais la première solution est mieux pour la gestion simple de flags.

Bye,

CN8890 et ARMv8 48 coeur

Bonjour,

 

Pour moi les CPU haute densité type Cavium ThunderX CN8890 ARMv8 sont l’avenir dans le monde des serveurs, AMD a beau sortir ces Opteron A1100, ont est loin des 4$ par cpu de pine64 ou 8$ par cpu des raspberry pi.

Point que je prends en compte:

  • $ par cpu
  • Consommation électrique
  • Architecture: gros PC comme les AMD Opteron A1100 < Cavium ThunderX CN8890, car:
  • Trop de hdd et pas assez de cpu ne servent a rien, faire une grosse grappe raid pour plusieurs cœur et donc vm ne me convaincs pas, JBOD -> risque de crash, RAID5 -> une machine consomme trop de hdd et tout les hdd seek. Un hdd par cpu ou par groupe de cpu a un sens, car ont peu allouer un hdd par vm, et donc éviter qu’une vm lente ne ralentisse les autres. Le H270-T70 A fait le choix de un disque par groupe de CPU ce qui a un sens dans l’augmentation de densité.
  • Avec 48 cpu ont peu gérer du 10Gbps voir plus (sous charge mixte: petit et grands packets + temps système), avec 8, même si ce sont des Cortex A57 je vois mal comment faire cela. Grace à la DDR4, les gros packets pourront être géré grâce à la bande passante mémoire. Citation de Erratasec:

    A standard Linux system that struggles at forwarding 500,000 packets-per-second

    , si les meilleurs x86 ont du mal, les ARM qui ont moins de instruction par secondes aux MHz…

Donc pour moi la carte H270-T70 de gigabyte est une bonne direction.

Bye,

IA, virus, sécurité, Cyberguerre

Salut,

J’ai vu un documentaire qui m’as fait bien rire: L’intelligence artificielle – Le régne des robots

Voila mes notes:

  • Oui une IA peu être plus intelligente, mais pas forcément, elle peu aussi bénéficier de la compression temporelle, avoir plusieurs entités qui transmette leur savoir de manière instantané (ne pas avoir de période d’apprentissage), ne plus être obligé de passé par la parole
  • Une AI n’est pas une programme dans le sens traditionnel. Si sont fonctionnement est multi ordinateur, tuer un groupe d’ordinateur reviens a tuer un groupe de neurone? C’est un peu comme faire dérailler notre cerveau, ça veux pas dire que le reste ne marchera pas.
  • La sécurité en informatique à évolué et continuera d’évoluer, il se peu qu’on tendra vers soit des systèmes parfait (vérification mathématique de la sécurité, compilation et/ou runtime), au même titre que les illusions d’optique cela peu affecté une zone temporairement.
  • Le cerveaux est capable de s’adapter, pourquoi pas les IA? S’auto programmer et boucher les failles. Si il sont pas trop bête elle vont essayé de s’auto pirater pour se sécuriser.
  • Pourquoi cela serai une IA et pas un être humain connecté cérébralement?
  • Tout les êtres ont en commun l’instinct de survie, le besoin de se reproduire, l’évolution et la divergence, et un certain nombre de facteur dépendant du monde physique. Le monde virtuel est différent, mais il as des limites aussi (nombre d’entité limité par le nombre d’instruction cpu par secondes). Si la reproduction se produit, allons nous voir des groupes social d’IA, des guerres, des défenses de territoires? Oublie totale des armes de cyber guerre.
  • Si une espèce est plus avancé au niveau de l’évolution, on sais très bien ce qui ce passe sur notre plante, faut arrêté de croire que l’homme est beau, grand, puissant et au centre de tout.

En ésperant vous avoir fait réfléchir. Bye

JIT et compilation

Bonjour,

Une langage informatique c’est une représentation d’une logique, celle si peu être orienté facilité (python, php) ou passé un maximum de détails au compilateur et étant proche du hardware (C, C++, ce qui permet de bien meilleur performance). Mais dans tout les cas il peu être compilé, interprété, JIT.

JIT pour wikipedia: Dans le domaine de la programmation informatique, la compilation à la volée, aussi connue sous le nom de traduction dynamique (just-in-time compilation ou JIT compilation en anglais), est une technique visant à améliorer la performance de systèmesbytecode-compilés par la traduction de bytecode en code machine natif au moment de l’exécution. La compilation à la volée se base sur deux anciennes idées : la compilation de bytecode et la compilation dynamique.

Que change le JIT?

  • Cela permet d’exploiter les instructions spéciales du CPU sans tuer la portabilité, si vous voulez utiliser SSE2, SSE4, AVX2, NEON dans votre application en la compilant avec gcc -msse2, … mais l’application crashera sur les cpu n’ayant pas cette instruction
  • En fonction de l’implémentation elle peu avoir des optimisations moins poussé que un compilateur, en échange de moins de temps de compilation. Qui veut attendre 5s avant d’afficher un simple hello world en php? Mais donc potentiellement vas moins loin dans les optimisations (dépends de l’implémentation!).
  • Dans un code compilé:

    var toto=fichier de config[Toto]
    if(toto==X)
    faire une chose
    else
    faire autre chose

    La condition vas toujours être vérifié, pas en JIT. Car le JIT vas détecter que après la première ligne la variable ne vas jamais changer, et donc vas faire cela:

    if(true)//la condition est toujours vraie/fausse car toto ne change jamais après avoir été changer du fichier de config
    faire une chose
    else
    faire autre chose

    Et vas donc finir par ne garder que la branche qui est toujours exécuté:

    faire une chose

    Wikipedia: La prédiction de branchement est une fonctionnalité d’un processeur qui lui permet de prédire le résultat d’un branchement. Cette technique permet à un processeur de rendre l’utilisation de son pipeline plus efficace. Avec cette technique, le processeur va faire de l’exécution spéculative : il va parier sur le résultat d’un branchement, et va poursuivre l’exécution du programme avec le résultat du pari. Si le pari échoue, les instructions chargées par erreur dans le pipeline sont annulées.
    Cela permet donc du diminuer ce besoin hardware, augmenter fortement les performances lors des hardwares n’ayant pas une prédiction de branchement performante. Dans tout les cas il est mieux de sortir les conditions de vos boucles et mettre des boucles différentes dans plusieurs branche, cela fait en effet similaire (mais cela peu varié en fonction du cas).

 

En espérant vous avoir éclairé avec cette article en français.

Comment augementer votre compression sans toucher au format de compression?

Bonjour,

Aujourd’hui nous allons parler de compression de données lossless (sans changement de l’information).
Cela vas s’appliquer surtout au MMORPG CatchChallenger sur les points suivant: données de taille petite et moyenne, fortement compressible (xml, base64 continue).

Choix de la compression

Même si dans ce post se n’est pas le but, il faut bien choisir votre compression en fonction de votre système. Si vous voulez plus de bande passante en échange de cpu, si vous faites la compression dynamiquement ou non, …

Ratio de compression

Temps de compression

Réduire l’entropie

Nous allons avant tout commencer à reduire l’entropie. Vous devez donc supprimer toutes les données aléatoire inutile. Et faire que celle utile forme des suites.

Isoler les bloques aléatoires

Quand un bloque de donnés viens couper des données similaire:

items/1073.png 1 XXXX
items/1149.png 1 XXXX
items/1178.png 1 XXXX

Cela casse la compression (le système de compression switch tout le de temps compressé a non compressé). Cela n’as pas d’importance sur les grands bloque car le changement de mode est mineur vis a vis de la taille du bloque à compresser. L’idée est donc de les mettre la la fin pour que la compression soit maximal d’un coté et que le système de compression marque simplement un gros bloque comme non compressible.

items/1073.png 1
items/1149.png 1
items/1178.png 1
XXXX
XXXX
XXXX

Cela fait gagné 20% sur le format au dessus.

Binaire et pas hexa

Les formats de compression sont très sensible aux données non compressibles, les mettre en binaire et pas en hexa permet de réduire leur taille (10%).

Contenu

En fonction du contenu ET de la taille certaine compression seront plus avantageuse. Par exemple la zlib/gzip est plus efficace que xz/lzma sur les packet <300o.

Il n’y as pas une compression meilleur que les autres, chaque une ont leurs caractéristiques et leurs caractéristiques vis à vis de certaines données.

Zopfli

Zopfli permet de garder le format de compression actuel, mais à énormément besoin de cpu, ne jamais l’utiliser en dynamique. Il réduit de 10% à 50% la taille de vos compressions zlib/gzip (donc png aussi)

Mon outils tmxTileLayerCompressor pour compresser les bloques zlib dans les tmx avec zopfli permet de réduire la taille des tmx même sous leur forme compressé d’environ 10%.

Chose étonnante je ne constate pas de réduction de taille du datapack.tar.xz comme prévu. Idem coté tar sans xz, je pense que la modification est noyé dans un volume tellement gros d’informations qu’elle n’as pas d’influence. Par contre sur les pngs zopfli a une une influence notable.

Brotli

Je doit tester cette compression qui semble sympa surtout pour le streaming réseau avec des bloques de plus de 800o. Une compression proche de xz pour le statique, mais plus performant que gzip en -6 pour le streaming réseau tout en conservant un trés bon ratio. Mais hélas je trouve qu’il est trop orienté décompression, car la compression est bien trop lente mon gout, où en -6 c’est trés proche ou inférieur au ratio de zlib en fonction du contenu. Comme zlib: C’est parallélisable? Possible accélération hardware?

Voir le super lien: https://quixdb.github.io/squash-benchmark/

Lossy

Pour certain fichier comme les png/audio, les compressions sont lossless (sans perte de qualité/informations) mais j’ai appliquer un filtre de compression lossy (perte de qualité/informations) pour réduire la taille.

CatchChallenger

Voila les résultats spécifiques à CatchChallenger pour la liste des fichiers à télécharger:

Binaire 7% de taille en moins pour gzip
Suppression des retours de ligne pour les hash partiel (données non compressibles: réduction de 10% pour xz, 7% pour gzip
La spéparation en deux fichier (l’un compressé l’autre non) fait gagné 100o mais qui sont perdu par le protocole http (2x les entêtes pour les deux fichiers)
Répartition de la taille pour la base:
* 7Ko pour la liste de fichiers
* 500o pour la taille des fichiers
* 12Ko pour les hash partiel (non compressible)
Répartition de la taille pour le main:
* 2200o pour la liste de fichiers
* 500opour la taille des fichiers
* 2200opour les hash partiel (non compressible)

Programmation Broadcast vs singlecast et chat

Bonjour,

J’avais vu une bétise sur internet disant qu’il valais mieux utiliser une serveur irc pour le chat de votre jeu pour les performances. Si vous êtes sur le même hardware et que irc fait beaucoup mieux alors c’est que vous avez mal codé votre programme.
Buffer
Le principe basique est d’envoyer le message à tout les clients connectés.  Si le buffer n’est pas assez grand, ou le message/liste de client trop grand, alors votre programme vas être bloqué à chaque écriture dans votre socket et donc ne vas pas pouvoir tourner. Vous pouvez pour contourner cela en l’isolant dans un thread (cela vaut pour tout les autres syscall bloquant) ou passer votre socket en mode non bloquant (plus de travail mais plus de performance).
Packaging
Vous avez plusieurs couche, hélas la plus par du temps vous ne pouvez pas directement accéder au buffer tcp, mais ce que je vais vous dire vaux pour les couches suppérieures. J’ajoute en header un code de packet et une taille, donc pour du broadcast je compose le packet complet (avec header), et je l’envoie, ce qui est bien plus efficace que de le recomposer à chaque fois inutilement (cela demande des fast path dans le code, et une décomposition total pour le controle de la sortie). Le CRC32 du tcp est aussi calculable qu’une seule fois, mais l’OS ne propose en générale pas d’interface pour cela.
Application tiers

Le faite de rajouter un application n’as de sens que si le client se connecte directement a elle et qu’elle est sur un autre serveur, mais personnelement je ne vois pas comment ont peu saturer un serveur irc ou un chat avec un usage normale. Le faite de communiquer entre le serveur et un autre serveur rajoute une couche tcp et de message qui fait plus de consomation cpu/réseau/mémoire.

Ces principes valent aussi pour les déplacements des joueurs qui sont aussi envoyé d’un block à tout les joueurs dans la même zone.
PS: avec un « \0 » bien placé ont peu cacher des données dans le chat de maniére discréte

CatchChallenger 2 et passage sur C++11

Salut,

J’ai fini la partie cluster de CatchChallenger 2, la localité des données est vraiment bonne, juste des petites réquetes pour un veroux global non bloquant sur les données communes et des serveurs indépendants. La passerelle avec cache (permet d’exposer un server sur TOR/I2P vers l’internet normal ou l’inverse), et les CDN sont aussi codés. L’infrastructure réseau est donc principalement prête pour fonctionner même dans les pires conditions: réseau trés lent <60Ko/s, ping/latence énorme: >800ms. Ce que semble confirmer les testes que j’ai pu faire via i2p et sur l’internet normal au travers du monde entier.
 
J’ai voulu faire des optimisations particuliérement de refesant le protocole, mais pour avoir un bon bon de vu sur ce qui est lent, j’ai besoin de refaire en C++11 le programme car les conteneur Qt sont lent (32x plus lent pour les chaines). Le version 11 me permet d’avoir accés a plein chose sur les containers, permet au compilateur de mieux optimiser le code, ajoute les regex, timer, temps, être plus portable sans recourrir a Qt. Cela vas me permettre aussi de faire des programmes avec trés peu de dépendance, et donc pouvoir les embarquer et cacher un peu partout. Ce remake vas être très long, surtout car je ne suis pas prêt pour le C++11 et que je doit donc tout apprendre. Ce qui est du standard, il permet de définir un certain nombre de propiété, par exemple les espace mémoire continu pour certain conteneur ContiguousContainer (for T other than bool) (since C++17) ou ContainerAllocatorAwareContainerSequenceContainer and ReversibleContainer tout cela permet d’être pris en compte par le compilateur et donc d’ouvrir des oportunités d’optimisation. Si elle pourront être profité par le compilateur et si elle le seront, seul l’avenir nous le dira. Donc oui, C++17 > C++14 > C++11 > C++99 > C++ pour les performance.
On pourra potentielement imaginer de puissant assitant de preuve avec les nouveaux standard pour détecter les failles potentielles, les cas de buffer overflow, … il ne feront pas tout, ce n’est qu’un outils, mais cela limitera les failles basiques, enseignera les bonnes habitudes.
 
J’ai mon portable datacenter qui est en ARM, ce qui me permet de tester mon jeu sur différente architecture (avec x86 sur Intel Atom z530 et AMD Geode LX800, et x86_64 Intel haswell) et tracker les possibles régréssions. J’ai ouvert les options de compression et rajouter lz4 pour comblé un vide, sur ARM les performances été desastreuses, j’ai donc ouvert quelques noeux pour l’auteur de xxhash et lz4, Yann Collet, que je salut en passant, qui as optimisé ces derniers pour ARMv6 et ARMv7.
Les changements pour le support des clusters sont donc fait, il reste ceux pour la portabilité, un énorme remake sur le protocole pour optimiser le parsage des packets. Il faut toujours différencier le format/algo/protocole de l’implémentation (comment c’est codé). C’est comme une maison, les plans peuvent être super mais la réalisassion pas génial.

 

 

 

Cluster ARM

arm-cluster
Cluster arm, cubox im cubieboard, rpi, odroid

Salut,

Je souhaite revenir sur quelque mois d’utilisation intensive de mon cluster ARM. L’image n’est pas celle actuel mais donne une idee de mon portable datacenter.

Je trouve dommage que pour avoir java 8, il faille utiliser le java de oracle et que ce dernier n’est pas actualisé et donc potentiellement avec des failles. Java est une technologie qui permet de faire fonctionner une application que vous soyez sur ARMv6, v7, x86. Mais cela ajoute une abstraction assez casse pieds qui bloque l’accès a certain truc spécifique de l’OS et ne permet de de descendre aussi bas dans le optimisation que en c/c++.

Nagios est performant, munin est pourri cote performance et plombe ces propres mesures (Surtout a cause du spawn de processus). Le backup sur une node en btrfs, le but étant d’avoir des backups différentiel.

Il faut faire très attention à la bande passante inter processus/thread qui est très réduite, sans même parler des communication externe. Donc il vaut mieux privilégier plusieurs processus mono thread qui travaille en local sur leur données locales que du multi-thread qui passe plus de temps à faire tourner les données entre plusieurs threads et se coordonner le travail que à travailler. L’ordonnanceur cpu vas naturellement repartir chaque processus par cpu (base de donnée, noyau, serveur authentification serveur de jeu). Le multi-thread peu être simpa si vous avec qu’un service sur un matos multi coeur (votre base donnée sur un quadcore, bien que dans ce cas l’ordonnanceur disk, le FS et le disque en lui même auront plus d’influence). Mon programme est plus simple est bien plus rapide sur ARM vu que je n’utilise pas de verrou, et je fait juste tourner plusieurs serveur en parallèle. Le joueur n’as plus qu’as jouer sur le même serveur que ces amis, ce qui déporte le problème du multi-thread sur l’humain. Cela permet que le serveur consomme 10-50x moins de cpu que le noyau linux pour gérer les packet tcp.

Grsec combiné à certain manque d’optimisation sur ARM (hardware comme software) fonds que certaines fonction sont bien plus lente (memcpy() vs accès non aligné, presque aucune différence de performance sur x86, ARM + grsec 7x plus performant sur les accès non aligné). Une taille fix en mémoire de l’application aide à ne pas faire de pression sur le code de gestion de la mémoire.

La consommation et prix de la puce est défini par le nombre de transistor dans la puce. Si vous avec une puce trop généraliste vous perdez sur cela, par exemple j’ai pas besoin du GPU ni du FPU pour mes serveur. Par contre j’ai besoin de l’ALU et des unités SIMD. J’aurai aussi besoin d’ASIC AES et SHA224, un générateur de nombre aléatoire pour optimiser la partie cryptographique des applications (connexion des utilisateurs, des serveurs aux bases de données, des serveurs entre eux). La communication chiffré est de nos jours obligatoire, donc le volume transmit via une connexion chiffré même établis en permanence a un impacte sur les performances, les accélérateur hardware se rapporte à un système de chiffré qui hélas se font brisé de plus en plus rapidement). Je n’est presque jamais vu d’accélération sur la compression, si cela est possible. Pas mal de puce ont démontré un meilleur ratio GFLOPS/W car leur circuit sont fix et optimisé. (GPU passage de statique, partiellement programmable, totalement programmable)

Finalement les performances son bien meilleur que un gros serveur x86 (15x la vitesse de la DDR3), plus de sécurité car il y as beaucoup moins de vm par hardware car il y as plus de hardware pour le même prix/consommation énergétique. Je suis très content de mon cluster MMORPG sur ce cluster qui peu tenir d’apres mes testes en gardant beaucoup de marge 30 hardware*4 cpu*100k utilisateur=12 millions de joueur pour moins de 100W.