Je reviens sur la question de la mémoire sur AMD.
Il y a, en substance, deux approches:
1- on prend des barettes de DDR4 référencées par AMD comme fonctionnelles sur AM4:
https://www.amd.com/system/files/2017-06/am4-motherboard-memory-support-list-en_0.pdf dans ce cas, la carte mère démarre facilement.
2- on lit attentivement le AMD Ryzen Memory Tweaking & Overclocking Guide disponible :
https://www.techpowerup.com/review/amd-ryzen-memory-tweaking-overclocking-guide/ J'insiste bien sur le côté indispensable de cette lecture. Autant sur Intel, du fait de l'âge des la plateforme et de l'écosystème, les fabricants de mémoire et de carte mères ont depuis longtemps pu collaborer pour pondre des réglages XMP rapides fonctionnels même si pas nécessairement optimaux, autant sur AMD, à par quelques références marquées "XMP AMD", le réglage XMP intel peut ne pas permettre à la carte mère de simplement démarrer.
Alors, on coche quelques paramètres, en comprenant mieux comment ils agissent, et on tâche de disposer des meilleures performances.
Je partais de 4x16Go de Corsair CMK32GX4M2B3200C16 en 3200 C16, référencées par la liste d'AMD de juin 2017 et j'essaie d'aller vers des 3600MHz C19, pour voir si je gratte en perf, ou non.
Références des nouvelles barrettes, Gskill Ripjaws V F4-3600C29D-32GVRB
https://www.amazon.fr/gp/product/B07CHL3TH7/ref=ox_sc_act_title_1?SubscriptionId=AKIAJS7NMDLEEDDDRG7Q&tag=gamerprices-cdh-21&linkCode=xm2&camp=2025
Comment évaluer la performance de la mémoire. S'arrêter à un test de vitesse monothread me semble simpliste. Il y a un contrôleur de mémoire, lié à l'Infinity Fabric, qui tourne au centre des CCX, dont la fréquence définit le rythme des transferts de mémoire inter coeur. Dit autrement, on peut manifestement avoir du gain, sous AMD AM4, à utiliser de la mémoire qui monte plus en fréquence, quitte à perdre un peu en latence.
Comment tester, comme évoqué plus haut ? On lance un zip vite fait sur un corpus de données, on vérifie si ça passe en mono ou multithread ?
Sous linux, c'est plus facile, avec quelques commandes bien trouvées, et un peu de colle bash. J'utilise donc le merveilleux travail de mon ami Zentoo, que je verse ici avec son autorisation. Il faut préalablement installer pv, lshw, dd, gzip, bzip2, xz, zip, lzop, pigz, pbzip2, lbzip2. Ne tiquez pas sur les fenêtres SIZE qui varient, l'objectif est de mesurer une vitesse de traitement maximale, conditionnée par le CPU et la vitesse de transfert cache<->mémoire. Le point d'équilibre de l'asymptote de la courbe apparaît plus ou moins vite, selon l'outil sutilisé, et le script est calibré pour produire des résultats en équilibre à intervalle régulier. Donc, la taille du corpus de données, ici des zéros, varie d'un outil à l'autre, et c'est normal. On pourrait utiliser un corpus de données fixes, mais interviendrait alors la vitesse en lecture de ces donnés, manipulées, puis stockées. Faisons simple, l'objectif, c'est la mesure de la scalabilité de la bande passante mémoire, donc on part de /dev/zero, qui fournit vite, pour saturer vite, et ne pas y passer la nuit.
#!/bin/bash
#
# zenbench.sh is a compilation of one liner bash benchmarks
#
# zentoo - 2019/07/09
requirements ()
{
STOP=0
for x in lshw dd gzip bzip2 xz zip lzop pigz pbzip2 lbzip2 ; do
if ! command -v $x >/dev/null ; then
echo "You need to have $x installed"
STOP=1
fi
done
[[ $STOP == 1 ]] && exit $STOP
}
cpuinfo ()
{
echo
echo "=== CPU ==="
# Load cpu to get cpu max speed
SIZE=256M ; dd if=/dev/zero bs=$SIZE count=1 2>/dev/null /bin/bzip2 > /dev/null &
lshw -class cpu | grep -E "product:|slot:|size:" | sed 's|.*product: ||;s|.*slot:|Socket:|;s|.*size:|Speed:|g'
lshw -class memory -short | grep -E "cache" | sed 's|.*memory *||g'
wait
}
meminfo ()
{
echo
echo "=== RAM ==="
lshw -class memory -short | grep -E "System Memory|DDR" | sed 's|.*memory *||g'
}
benchs ()
{
echo
echo "=== Single thread benchmarks ==="
SIZE=16G ; dd if=/dev/zero bs=$SIZE count=1 2>/dev/null | pv -aWi0.1 -N dd > /dev/null
SIZE=1G ; dd if=/dev/zero bs=$SIZE count=1 2>/dev/null | pv -aWi0.1 -N gzip | /bin/gzip > /dev/null
SIZE=1G ; dd if=/dev/zero bs=$SIZE count=1 2>/dev/null | pv -aWi0.1 -N bzip2 | /bin/bzip2 > /dev/null
SIZE=512M ; dd if=/dev/zero bs=$SIZE count=1 2>/dev/null | pv -aWi0.1 -N xz | xz > /dev/null
SIZE=1G ; dd if=/dev/zero bs=$SIZE count=1 2>/dev/null | pv -aWi0.1 -N zip | zip -q > /dev/null
SIZE=8G ; dd if=/dev/zero bs=$SIZE count=1 2>/dev/null | pv -aWi0.1 -N lzop | lzop > /dev/null
echo
echo "=== Multi threads benchmarks ==="
SIZE=8G ; dd if=/dev/zero bs=$SIZE count=1 2>/dev/null | pv -aWi0.1 -N pigz | pigz > /dev/null
SIZE=8G ; dd if=/dev/zero bs=$SIZE count=1 2>/dev/null | pv -aWi0.1 -N pbzip2 | pbzip2 > /dev/null
SIZE=16G ; dd if=/dev/zero bs=$SIZE count=1 2>/dev/null | pv -aWi0.1 -N lbzip2 | lbzip2 > /dev/null
echo
echo "=== Threads scalability benchmarks ==="
SIZE=512 ; for p in $(seq $(nproc)); do dd if=/dev/zero count=1 bs=$(( $SIZE * $p ))M 2>/dev/null | pv -aWi0.1 -N "pbzip2 $p/$(nproc)" | pbzip2 -p$p > /dev/null ; done
SIZE=1024 ; for p in $(seq $(nproc)); do dd if=/dev/zero count=1 bs=$(( $SIZE * $p ))M 2>/dev/null | pv -aWi0.1 -N "lbzip2 $p/$(nproc)" | lbzip2 -n$p > /dev/null ; done
echo
}
# MAIN
requirements
cpuinfo
meminfo
benchs
https://framagit.org/Wax/zenbench/blob/master/zenbench.shVoici donc le résultat à 3000MHz avec les barettes Corsair @3200-C16, réglage stock XMP forcées à 3000MHz, rapide et sale:
# zenbench.sh @3000
=== CPU ===
AMD Ryzen 9 3900X 12-Core Processor
Socket: AM4
Speed: 3800MHz
768KiB L1 cache
6MiB L2 cache
64MiB L3 cache
=== RAM ===
64GiB System Memory
16GiB DIMM DDR4 Synchronous Unbuffered (Unregistered) 3000 MHz (0,3 ns)
16GiB DIMM DDR4 Synchronous Unbuffered (Unregistered) 3000 MHz (0,3 ns)
16GiB DIMM DDR4 Synchronous Unbuffered (Unregistered) 3000 MHz (0,3 ns)
16GiB DIMM DDR4 Synchronous Unbuffered (Unregistered) 3000 MHz (0,3 ns)
=== Single thread benchmarks ===
dd: [7,27GiB/s]
gzip: [ 220MiB/s]
bzip2: [ 147MiB/s]
xz: [77,5MiB/s]
zip: [ 214MiB/s]
lzop: [2,07GiB/s]
=== Multi threads benchmarks ===
pigz: [1,00GiB/s]
pbzip2: [2,27GiB/s]
lbzip2: [3,39GiB/s]
=== Threads scalability benchmarks ===
pbzip2 1/24: [ 151MiB/s]
pbzip2 2/24: [ 306MiB/s]
pbzip2 3/24: [ 455MiB/s]
pbzip2 4/24: [ 597MiB/s]
pbzip2 5/24: [ 738MiB/s]
pbzip2 6/24: [ 884MiB/s]
pbzip2 7/24: [1021MiB/s]
pbzip2 8/24: [1,14GiB/s]
pbzip2 9/24: [1,28GiB/s]
pbzip2 10/24: [1,37GiB/s]
pbzip2 11/24: [1,48GiB/s]
pbzip2 12/24: [1,58GiB/s]
pbzip2 13/24: [1,62GiB/s]
pbzip2 14/24: [1,66GiB/s]
pbzip2 15/24: [1,77GiB/s]
pbzip2 16/24: [1,84GiB/s]
pbzip2 17/24: [1,90GiB/s]
pbzip2 18/24: [1,93GiB/s]
pbzip2 19/24: [2,01GiB/s]
pbzip2 20/24: [2,06GiB/s]
pbzip2 21/24: [2,12GiB/s]
pbzip2 22/24: [2,19GiB/s]
pbzip2 23/24: [2,25GiB/s]
pbzip2 24/24: [2,26GiB/s]
lbzip2 1/24: [ 456MiB/s]
lbzip2 2/24: [ 908MiB/s]
lbzip2 3/24: [1,32GiB/s]
lbzip2 4/24: [1,73GiB/s]
lbzip2 5/24: [2,15GiB/s]
lbzip2 6/24: [2,56GiB/s]
lbzip2 7/24: [2,99GiB/s]
lbzip2 8/24: [3,41GiB/s]
lbzip2 9/24: [3,43GiB/s]
lbzip2 10/24: [3,44GiB/s]
lbzip2 11/24: [3,42GiB/s]
lbzip2 12/24: [3,43GiB/s]
lbzip2 13/24: [3,43GiB/s]
lbzip2 14/24: [3,42GiB/s]
lbzip2 15/24: [3,42GiB/s]
lbzip2 16/24: [3,41GiB/s]
lbzip2 17/24: [3,41GiB/s]
lbzip2 18/24: [3,41GiB/s]
lbzip2 19/24: [3,42GiB/s]
lbzip2 20/24: [3,42GiB/s]
lbzip2 21/24: [3,41GiB/s]
lbzip2 22/24: [3,43GiB/s]
lbzip2 23/24: [3,41GiB/s]
lbzip2 24/24: [3,41GiB/s]
On voit combien la bande passante est saturée par 10 coeurs sous lbpzip2 avec ces barrettes et ces réglages XMP @3200 stock downclocké à 3000.
Plaçons les barettes 3600, downclockées à 3200MHz:
=== CPU ===
AMD Ryzen 9 3900X 12-Core Processor
Socket: AM4
Speed: 3800MHz
768KiB L1 cache
6MiB L2 cache
64MiB L3 cache
=== RAM ===
32GiB System Memory
16GiB DIMM DDR4 Synchronous Unbuffered (Unregistered) 3200 MHz (0,3 ns)
16GiB DIMM DDR4 Synchronous Unbuffered (Unregistered) 3200 MHz (0,3 ns)
=== Single thread benchmarks ===
dd: [7,62GiB/s]
gzip: [ 211MiB/s]
bzip2: [ 144MiB/s]
xz: [74,7MiB/s]
zip: [ 208MiB/s]
lzop: [1,77GiB/s]
=== Multi threads benchmarks ===
pigz: [1,10GiB/s]
pbzip2: [2,09GiB/s]
lbzip2: [4,10GiB/s]
=== Threads scalability benchmarks ===
pbzip2 1/24: [ 150MiB/s]
pbzip2 2/24: [ 293MiB/s]
pbzip2 3/24: [ 435MiB/s]
pbzip2 4/24: [ 572MiB/s]
pbzip2 5/24: [ 728MiB/s]
pbzip2 6/24: [ 872MiB/s]
pbzip2 7/24: [ 998MiB/s]
pbzip2 8/24: [1,12GiB/s]
pbzip2 9/24: [1,26GiB/s]
pbzip2 10/24: [1,32GiB/s]
pbzip2 11/24: [1,49GiB/s]
pbzip2 12/24: [1,65GiB/s]
pbzip2 13/24: [1,67GiB/s]
pbzip2 14/24: [1,74GiB/s]
pbzip2 15/24: [1,78GiB/s]
pbzip2 16/24: [1,82GiB/s]
pbzip2 17/24: [1,89GiB/s]
pbzip2 18/24: [1,95GiB/s]
pbzip2 19/24: [2,00GiB/s]
pbzip2 20/24: [2,06GiB/s]
pbzip2 21/24: [2,12GiB/s]
pbzip2 22/24: [2,16GiB/s]
pbzip2 23/24: [2,21GiB/s]
pbzip2 24/24: [2,13GiB/s]
lbzip2 1/24: [ 457MiB/s]
lbzip2 2/24: [ 881MiB/s]
lbzip2 3/24: [1,28GiB/s]
lbzip2 4/24: [1,71GiB/s]
lbzip2 5/24: [2,14GiB/s]
lbzip2 6/24: [2,55GiB/s]
lbzip2 7/24: [2,98GiB/s]
lbzip2 8/24: [3,37GiB/s]
lbzip2 9/24: [3,74GiB/s]
lbzip2 10/24: [3,77GiB/s]
lbzip2 11/24: [4,35GiB/s]
lbzip2 12/24: [3,57GiB/s]
lbzip2 13/24: [4,10GiB/s]
lbzip2 14/24: [4,17GiB/s]
lbzip2 15/24: [4,79GiB/s]
lbzip2 16/24: [3,82GiB/s]
lbzip2 17/24: [3,73GiB/s]
lbzip2 18/24: [3,73GiB/s]
lbzip2 19/24: [3,55GiB/s]
lbzip2 20/24: [4,52GiB/s]
lbzip2 21/24: [3,57GiB/s]
lbzip2 22/24: [3,62GiB/s]
lbzip2 23/24: [3,55GiB/s]
lbzip2 24/24: [3,88GiB/s]
time emerge sys-devel/gcc
real 20m23,957s
user 136m39,371s
sys 13m52,687s
lpbzip2 sature à 15 threads.
On note que la bande passante augmente un peu, et j'y colle un temps de compilation de gcc.
Maitenant, montons les barrettes à leur vitesse proposée, 3600-C19:
=== CPU ===
AMD Ryzen 9 3900X 12-Core Processor
Socket: AM4
Speed: 3800MHz
768KiB L1 cache
6MiB L2 cache
64MiB L3 cache
=== RAM ===
32GiB System Memory
16GiB DIMM DDR4 Synchronous Unbuffered (Unregistered) 3600 MHz (0,3 ns)
16GiB DIMM DDR4 Synchronous Unbuffered (Unregistered) 3600 MHz (0,3 ns)
=== Single thread benchmarks ===
dd: [7,71GiB/s]
gzip: [ 209MiB/s]
bzip2: [ 144MiB/s]
xz: [75,7MiB/s]
zip: [ 206MiB/s]
lzop: [1,80GiB/s]
=== Multi threads benchmarks ===
pigz: [1,08GiB/s]
pbzip2: [2,12GiB/s]
lbzip2: [4,59GiB/s]
=== Threads scalability benchmarks ===
pbzip2 1/24: [ 151MiB/s]
pbzip2 2/24: [ 298MiB/s]
pbzip2 3/24: [ 442MiB/s]
pbzip2 4/24: [ 585MiB/s]
pbzip2 5/24: [ 731MiB/s]
pbzip2 6/24: [ 872MiB/s]
pbzip2 7/24: [1005MiB/s]
pbzip2 8/24: [1,11GiB/s]
pbzip2 9/24: [1,25GiB/s]
pbzip2 10/24: [1,37GiB/s]
pbzip2 11/24: [1,48GiB/s]
pbzip2 12/24: [1,62GiB/s]
pbzip2 13/24: [1,67GiB/s]
pbzip2 14/24: [1,73GiB/s]
pbzip2 15/24: [1,79GiB/s]
pbzip2 16/24: [1,85GiB/s]
pbzip2 17/24: [1,88GiB/s]
pbzip2 18/24: [1,95GiB/s]
pbzip2 19/24: [2,00GiB/s]
pbzip2 20/24: [2,06GiB/s]
pbzip2 21/24: [2,10GiB/s]
pbzip2 22/24: [2,17GiB/s]
pbzip2 23/24: [2,20GiB/s]
pbzip2 24/24: [2,19GiB/s]
lbzip2 1/24: [ 440MiB/s]
lbzip2 2/24: [ 881MiB/s]
lbzip2 3/24: [1,29GiB/s]
lbzip2 4/24: [1,70GiB/s]
lbzip2 5/24: [2,12GiB/s]
lbzip2 6/24: [2,55GiB/s]
lbzip2 7/24: [2,99GiB/s]
lbzip2 8/24: [3,39GiB/s]
lbzip2 9/24: [3,79GiB/s]
lbzip2 10/24: [4,16GiB/s]
lbzip2 11/24: [4,12GiB/s]
lbzip2 12/24: [4,15GiB/s]
lbzip2 13/24: [3,92GiB/s]
lbzip2 14/24: [4,11GiB/s]
lbzip2 15/24: [4,07GiB/s]
lbzip2 16/24: [4,25GiB/s]
lbzip2 17/24: [4,97GiB/s]
lbzip2 18/24: [4,23GiB/s]
lbzip2 19/24: [4,30GiB/s]
lbzip2 20/24: [4,16GiB/s]
lbzip2 21/24: [4,02GiB/s]
lbzip2 22/24: [3,86GiB/s]
lbzip2 23/24: [4,12GiB/s]
lbzip2 24/24: [4,11GiB/s]
-----
time emerge dev-sys/gcc
real 20m9,441s
user 136m53,590s
sys 13m31,306s
Si l'on s'attache bien à ces résultats, on note qu'à 3200MHz, lpbzip2 sature à 15 threads, mais à 17 threads à 3600MHz.
Il y a un gain à la compilation de gcc, qui compile de façon stable.
Spread the word.
Je vais installer les 2 autres barrettes en 3600, et voir ce que ça donne en compilation massive.
Gnubyte