Bon,
Je vais commencer par un petit speach sur le fonctionnement d'une flash.
Pour accéder à une mémoire flash, une adresse est définie par page (p = puissance de 2, par exemple 8KB), secteur (x pages) et bank (y secteurs).
Pourquoi cette subdivision ?
Parce que quand on fait un accès à la flash, la mémoire convertie l'adresse donnée en une page qu'elle charge ensuite dans un buffer (mémoire) interne. Ce qui permet à la flash une fois la page préchargée d'envoyer les données très rapidement (burstée). La page est donc le plus petit élèment accédé sur une flash. Ensuite x pages (tjrs une puissance de 2) forment un secteur. Un secteur est le plus petit élèment effaçable sur une flash. Dans une flash on n'efface jamais une page mais un secteur tout entier. Il faut noter que l'effacement d'un secteur de flash prend un temps très long (par rapport à la lecture). Sur les premières flash (NOR) cela pouvait prendre de l'ordre de quelques centaines de ms.... Maintenant ça c'est amélioré mais bon cela reste très long. Enfin la bank est la dernière séparation. Une bank est le nombre de secteurs auquel il ne faut plus accéder lors d'un effacement. Et oui, l'effacement d'un secteur étant très long, c'est fait de manière asynchrone (ordre d'effacement, puis lecture à intervalle régulier du status). Problème, il faut laisser la flash "travailler" et donc ne pas accéder aux données en cours d'effacement. Mais en fait c'est même plus compliqué que cela, c'est toute une bank (y secteurs) qui est inaccessible lors d'un effacement.
Pour résumer:
- page: plus petit élèment accédé
- secteur: plus petit élèment effacé
- bank: plus petit élèment inaccessible lors d'un effacement
Côté fonctionnement, une flash contient initialement que des bits à 1, et une écriture consiste à mettre à zéro des bits sur une page. On peut réécrire une page, seuls les nouveaux bits à zéros seront écrits. Il n'est donc pas possible d'écrire un bit à 1. Et donc un effacement consiste à remettre TOUS les bits d'un secteur à 1. Et enfin il faut savoir qu'une page supporte un nombre limite d'écriture de zéros avant de commencer à flancher (= ne pas écrire le zéro). Sur les premiers modèles c'était de l'ordre de plusieurs milliers, maintenant cela se compte en centaines... Mais bon, cela reste des statistiques.
Vous commencez à voir les problèmes avec les filesystem conçus pour fonctionner avec un disque dur (et donc possible d'écrire des zéros et des 1 dans un secteur) ?
Un processeur flash fait donc y*x*p bytes.
Du moins commercialement, car une page c'est un peu plus qu'une puissance de 2...
En fait, il est d'usage de rajouter quelques octets APRES la page. Je ne me rappelle plus combien mais c'est de l'ordre de 16 octets par KO. Pourquoi ces données en plus ? En fait il y a plusieurs raisons à cela:
- cela contient un code correcteur d'erreur (3 octets/512 octets) qui permet de détecter et potentiellement corriger une erreur d'un bit (un seul)/512 octets
- cela contient surtout des paramètres sur l'état de la page et qui est propre à l'algorithme implèmenté dans le contrôleur et qui va s'interfacer avec le PC
Quoi qu'il en soit, dans un SSD affiché à 960GB, il y a des chances pour qu'il y ait au moins 1TB voir même beaucoup plus, ceci sans compter les données extras par page.
Bon, toute cette introduction est là pour dire qu'au final ce qui donne de bonne performances à un SSD c'est surtout l’intelligence (= l'algorithme) de son contrôleur.
En effet, celui ci devra gérer: plusieurs chip flash en parallèle, plusieurs bank inaccessibles lors des effacements, le wear-leveling (= répartition du nombre d'écriture sur la totalité de la flash), et tout ça en prenant bien garde de ne pas perdre de données si le courant est coupé.
D'ailleurs, comme le wear-leveling est très (de plus en plus) important, on va détailler un peu ce que cela doit faire.
Pour le wear-leveling, cela est important car comme une page à un nombre (de plus en plus) limité d'écriture avant erreur, cet algorithme doit répartir les écritures sur le plus de pages différentes de flash possible (donc sur la totalité de la flash). Cela implique obligatoirement que le contrôleur est capable de faire une translation d'adresse du type secteur logique (LBA) -> adresse en flash (complètement différente). Et si jamais une écriture dans un secteur logique a lieu, il faut que le contrôleur choisisse une nouvelle adresse en flash vierge (effacée), écrive les nouvelles données dessus, sauvegarde dans sa structure la nouvelle translation LBA->adresse, et enfin marque la précédente adresse en flash comme "invalide - à effacer". C'est aussi pour ça qu'il y a toujours plus de flash qu'affiché (genre 1TB pour 960GB affiché), cela permet à l'algorithme de wear-leveling de toujours trouver une page vierge.
Avec le wear-leveling vient aussi le garbage collector. Son but c'est d'effacer la flash en background en se basant sur les pages marquées "à effacer". Par exemple quand un secteur logique LBA a été écrit 2 fois. Là c'est facile, l'ancienne adresse en flash de la première écriture doit être effacé. A noter, le TRIM aide énormèment. Dans un filesystem classique prévue pour un disque dur lent, effacer un fichier consiste juste à réécrire quelques secteurs contenant la position du fichier sur le disque et voilà. Ce qui fait qu'avec un SSD on se retrouve avec des données effacés sur le filesystem mais pas en flash et là le garbage collector rame pour trouver des secteurs à effacer. Alors qu'avec le TRIM, on envoi en plus toute la position du fichier effacé sur le disque au controleur du SSD qui peut directement marquer les pages de la totalité du fichier comme "à effacer". Mais comme sur une flash on n'efface pas une page mais un secteur, comment on fait ? Et là c'est la magie du garbage collector qui parfois se retrouve à déplacer quelques pages pour effacer tout un secteur.
Et enfin, si jamais le contrôleur tombe sur une page qui nécessite une correction d'erreur, la page doit être marqué comme "à ne plus utiliser" et les données déplacées sur une nouvelle page.
En fait les problèmes que les contrôleurs doivent gérer en plus avec les filesystem:
- la translation LBA->adresse en flash
- la réécriture d'un secteur
- je n'en ai pas parlé, mais un secteur logique ne fait pas forcement la taille d'une page (512B ou 4KB vs des pages de 8KB parfois)
- le TRIM qui permet de marquer très tôt un fichier à effacer
- le pool de pages vierges
Voilà donc ce qui fait que 2 benchmark ne donnent que rarement le même résultat:
- la translation LBA->adresse en flash peut prendre plus de temps suivant qu'il s'agit d'un secteur jamais accédé avant ou pas
- la translation LBA->adresse en flash peut prendre plus de temps suivant qu'il y ait une grosse fragmentation
- si le garbage collector travail plus ou moins
- suivant le remplissage du SSD
- suivant les performances au globale du contrôleur
- s'il y a des effacements à gérer en parallèle
- ou pas...
- si on écrit que des 1
....
Bref le benchmark rapide d'un SSD cela ne sert quasi à rien pour avoir une idée de ce que cela donnera en condition réelle.
Mes conseils sur les SSD:
- bien vérifier que le TRIM arrive bien aux SSD malgré le RAID
- aider le garbage collector en allouant des partitions un peu plus petites que la taille du disque (genre 10/15% en moins) même s'il y a déjà de la mémoire en plus
- faire plus confiance aux sites qui vérifient la stabilité des performances suivant le remplissage
- les meilleurs performances seront souvent atteint pour une quantité limité de données