Double channel RAM speed

Gast #4676840
Lesenswert?

Moin werte Anwesenden,

ich habe mir die Zeit ein wenig mit einem RAM Geschwindigkeitstest 
vertrieben und etwas Ungewöhnliches festgestellt.
Verbaut in einem core i5 System sind zwei 4GB Speicher DDR3-1333.
Die Bänke sind korrekt belegt!
Die Erwartungshaltung war das sich in etwa die avisierte 'Dual Rate' 
Geschwindigkeit einstellt.

Das Testprogramm nutzt C für Berechnungen und Darstellung, die 
Zeitmessung wird mittels mundgeblasener Assemblerfunktionen 
durchgeführt.

Beim linearen Lesen eines korrekt ausgerichteten 1GiB Speicherbereiches 
stellen sich erwartungsgemäß die ca. 21.2 GB/s ein. Der 'Dual Channel' 
Mode scheint also zu greifen.

Beim linearen Schreiben dieses Speicherbereiches mit einer nahezu 
identischen Assemblerfunktion bei der nur movq (pRam), %r9 gegen movq 
%r9, (pRam) getauscht wurde, stellt sich jedoch nur die halbe 
Geschwindigkeit (10.6 GB/s) ein.


FRAGE: Ist der 'Dual Channel' Mode nur bei Lesevorgängen aktiv?
Hat jemand eine Erklärung?

Ach ja, 64bit Debian GNU/Linux System

1
#   Chip        Modul       Mem    I/O     Eff     Rate   Rate
2
#                           clk    clk     clk   Single   Dual
3
#                           MHz    MHz     MHz     GB/s   GB/s
4
#   DDR3-1333   PC3-10600   166    666    1333     10,6   21,2
5
#   DDR3-1600   PC3-12800   200    800    1600     12,8   25,6
6
#
7
#   Source: https://de.wikipedia.org/wiki/DDR-SDRAM#DDR3-SDRAM
8

9
norbert@Entwicklung:~/source/testarea$ make Memspeed && ./Memspeed 
10
gcc -c -Wall -Wextra -pedantic -std=c11 -Os -o Memspeed.o Memspeed.c
11
gcc -c -Wall -Wextra -pedantic -std=c11 -O0 -fverbose-asm -o assemblerfunctions.o assemblerfunctions.S
12
gcc -Wl,--gc-sections -o Memspeed Memspeed.o assemblerfunctions.o
13
objdump -d -M motorola -S assemblerfunctions.o > assemblerfunctions.lst
14
strip Memspeed
15
ls -l Memspeed
16
-rwxr-x--- 1 norbert norbert 17360 Aug  9 14:02 Memspeed
17

18
Readspeed:
19
[   161590580]    21.26 GB/s (tsc based)
20
[   160432252]    21.42 GB/s (tsc based)
21
[   161857096]    21.23 GB/s (tsc based)
22
[   161606158]    21.26 GB/s (tsc based)
23
[   161181721]    21.32 GB/s (tsc based)
24
[   161021076]    21.34 GB/s (tsc based)
25
[   161154556]    21.32 GB/s (tsc based)
26
[   160926652]    21.35 GB/s (tsc based)
27
[   160661614]    21.39 GB/s (tsc based)
28
[   160569907]    21.40 GB/s (tsc based)
29
Usedtime:      0.504592 s (per iteration)
30
Bytes written: 10737418240  (10 GiB)
31
Speed:         21.28 GB/s   (19.82 GiB/s)
32

33
Writespeed:
34
[   322020040]    10.67 GB/s (tsc based)
35
[   322910643]    10.64 GB/s (tsc based)
36
[   321653569]    10.68 GB/s (tsc based)
37
[   322736627]    10.65 GB/s (tsc based)
38
[   321136953]    10.70 GB/s (tsc based)
39
[   321401221]    10.69 GB/s (tsc based)
40
[   321466218]    10.69 GB/s (tsc based)
41
[   322827836]    10.64 GB/s (tsc based)
42
[   323528069]    10.62 GB/s (tsc based)
43
[   322243548]    10.66 GB/s (tsc based)
44
Usedtime:      1.009161 s (per iteration)
45
Bytes written: 10737418240  (10 GiB)
46
Speed:         10.64 GB/s   (9.91 GiB/s)
47
norbert@Entwicklung:~/source/testarea$
Gast #4678466
Lesenswert?

Jim M. schrieb:
> Verwendet Linux beim Speicher nicht eine Copy-On-Write Strategie?
>
> Time mal einen 2. Schreibversuch im selben Progrtamm auf denselben
> Speicherbereich. Es kann sein dass der erst während des Schreibvorgangs
> allokiert wird, was das Timing dann versaut.

Ja, das macht Linux so.
Darum allokiere ich den Speicher (1 GiB) und beschreibe ihn zuerst mit 
memset() komplett.
1
uint64_t * prepare(void) {
2
    uint64_t *p;
3
    cpu_set_t mask;
4

5
    CPU_ZERO(&mask);
6
    CPU_SET(0,&mask);
7
    sched_setaffinity(0, sizeof(cpu_set_t), &mask);
8
    nice(-10);
9
    p = aligned_alloc(64*KIB, GIB);
10
    assert(p);
11
    memset(p, 0, GIB);
12
    return p;
13
}
Dann erst finden die Tests statt.
Es werden dann zehn mal hintereinander jeweils ein GiB in diesen 
Speicherbereich geschrieben bzw. aus dem Bereich gelesen.
Gast #4679668
Lesenswert?

Heiner schrieb im Beitrag #4679636:
> Norbert schrieb:
>> Darum allokiere ich den Speicher (1 GiB) und beschreibe ihn zuerst mit
>> memset() komplett.
>
> dann ist doch alles korrekt!
>
> lg Heiner

Erklär bitte mal was du damit meinst.

Und vor allem was es mit single vs. double channel mode zu tun hat.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren