2016-01-05 1 views
3

Je cours des tests de performance sur une implémentation de collection personnalisée avec JMH.Repères asymétriques dans JMH

Je voudrais imiter un scénario, où le nombre de lectures est 10 fois plus grand que le nombre d'écritures.

I utilisé this exemple de référence asymétrique et a créé un groupe de 10 fils de lecture et d'écriture fil 1:

@Benchmark 
@BenchmarkMode(Mode.AverageTime) 
@OutputTimeUnit(TimeUnit.MICROSECONDS) 
@Group("g0") 
@GroupThreads(1)  
public void baselinePut0(CacheState0 state) { writing } 

@Benchmark 
@BenchmarkMode(Mode.AverageTime) 
@OutputTimeUnit(TimeUnit.MICROSECONDS) 
@Group("g0") 
@GroupThreads(10) 
public Integer baselineGet0(CacheState0 state) { reading } 

je lance le test avec -wi 10 -i 10 -f 1 params. Dans un rapport, la variable cnt est identique pour tous les points de référence:

Benchmark     Mode Cnt  Score  Error Units 
Benchmark.g0    avgt 10 262,537 ? 215,406 us/op 
Benchmark.g0:baselineGet0 avgt 10  2,101 ? 0,154 us/op 
Benchmark.g0:baselinePut0 avgt 10 1252,231 ? 697,807 us/op 

Est-ce que cela signifie que nombre de lectures était égal au nombre d'écritures dans l'expérience? Si oui, comment l'implémenter correctement? Et plus général: ai-je oublié quelque chose dans cette configuration?

+0

À moins que vous * vraiment * besoin d'obtenir les mesures séparées pour les lectures/écritures, je préfère aller avec un test symétrique (aléatoire) qui jette le dé soutenu par ThreadLocalRandom s'il doit faire une lecture ou une écriture. De cette façon, vous équilibrez le mélange d'opérations avec plus d'attention et ne dépendez pas de la planification des threads. Vous ne courez pas sur la machine qui peut accueillir 11 threads en cours d'exécution sans se marcher les uns sur les autres, êtes-vous? ;) –

Répondre

1

Cnt indique le nombre d'échantillons (pas le nombre de fils). Dans votre cas, il est 10, puisque vous exécutez votre test avec -i 10. Il sera plus facile de voir que ce paramètre n'est pas nombre de threads si vous l'exécutez avec tous les params mis à des valeurs uniques (par exemple -i 13, alors que @GroupThreads(10) reste le même)

Vous pouvez également (temporaire) ajoutez la ligne de sortie votre test et voir d'où vient chaque fil, par exemple pour le lecteur (et similaire pour l'écrivain avec le mot « écrivain »):

System.out.println("reader " + Thread.currentThread().getName()); 
+0

cela signifie que le nombre de lectures était de 10 et le nombre d'écritures était de 10. savez-vous comment atteindre l'objectif que j'ai décrit dans une question? – AdamSkywalker

+0

Cnt n'est pas le nombre de lectures/écritures, c'est le nombre d'échantillons. Vous ne connaissez pas le nombre de lectures/écritures, puisque Mode.AverageTime fera autant d'opérations que possible [dans les limites de temps] (http://hg.openjdk.java.net/code-tools/jmh/file/ bcec9a03787f/jmh-samples/src/main/java/org/openjdk/jmh/samples/JMHSample_02_BenchmarkModes.java) Mais en repensant, je trouve que 'Cnt' dans votre cas devrait être 100, alors peut-être que vous avez oublié de fournir le nombre de threads, ie '@Threads (11)' sur la classe ou '-t 11' comme paramètre de ligne de commande? Si vous ne l'avez pas fait, le test fonctionnerait avec 1 thread au total (je pense) –

+1

Vous obtenez correctement 10 échantillons pour chaque sous-test, car les échantillons d'itération sont également (en mode "avgt") moyennés sur les threads participants. Ainsi, à chaque itération, le test "put" obtient un échantillon à partir d'un seul thread, et le test "get" obtient un échantillon moyenné sur 10 threads. Avec 10 itérations, vous obtenez 10 échantillons dans les deux sous-tests. C'est à peu près la même chose qu'avec les tests de "débit" multithread: un échantillon par itération est un débit de somme sur tous les threads. –