Caractéristiques de performance du fichier mappé en mémoire

Contexte:

J’ai une application Java qui effectue des E / S intensives sur des fichiers mappés en mémoire assez volumineux (> 500 Mo). Le programme lit les données, écrit des données et parfois les deux.

Toutes les fonctions de lecture / écriture ont une complexité de calcul similaire.

J’ai comparé la couche IO du programme et j’ai remarqué d’étranges caractéristiques de performance des fichiers mappés en mémoire:

  • Il effectue 90 000 lectures par seconde (lire 1 Ko à chaque itération au hasard)
  • Il effectue 38 000 écritures par seconde (écrivez 1 Ko chaque itération séquentiellement)
  • Il effectue 43k écritures par seconde (écrire 4 octets à chaque itération au hasard)
  • Il effectue seulement 9k opérations combinées en lecture / écriture par seconde (lire 12 octets puis écrire 1 Ko à chaque itération, au hasard)

Les programmes sur JDK 1.7, Linux 3.4 64 bits.

La machine est un PC Intel ordinaire avec 8 threads CPU et 4 Go de mémoire physique. Seulement 1 Go a été affecté au segment de mémoire JVM lors de la réalisation du test.

Si plus de détails sont nécessaires, voici le code de référence: https://github.com/HouzuoGuo/Aurinko2/blob/master/src/test/scala/storage/Benchmark.scala

Et voici l’implémentation des fonctions de lecture, écriture, lecture / écriture ci-dessus: https://github.com/HouzuoGuo/Aurinko2/blob/master/src/main/scala/aurinko2/storage/Collection.scala

Donc mes questions sont:

  • Compte tenu de la taille du fichier et de la taille de la mémoire, quels facteurs affectent les performances de lecture aléatoire des fichiers mappés en mémoire?
  • Étant donné la taille de fichier et la taille de la mémoire fixes, quels sont les facteurs qui affectent les performances d’écriture aléatoire de fichiers mappés en mémoire?
  • Comment puis-je expliquer le résultat de référence d’une opération combinée lecture / écriture? (Je m’attendais à ce qu’il effectue plus de 20 000 itérations par seconde).

Je vous remercie.

Les performances du fichier mappé en mémoire dépendent des performances du disque, du type de système de fichiers, de la mémoire disponible pour le cache du système de fichiers et de la taille des blocs de lecture / écriture. La taille de la page sur Linux est 4K. Donc, vous devriez vous attendre à la plupart des performances avec lecture / écriture 4k. Un access à une position aléatoire provoque un défaut de page si la page n’est pas mappée et va extraire une nouvelle page. Généralement, vous voulez un fichier mappé en mémoire si vous voulez voir les fichiers en tant que tableau de mémoire unique (ou ByteBuffer en Java).