ΠΠ΄Π½Π°ΠΆΠ΄Ρ ΠΌΠ½Π΅ ΡΠ»ΡΡΠ°ΠΉΠ½ΠΎ ΠΏΠΎΠΏΠ°Π»ΡΡ Π½Π° Π³Π»Π°Π·Π° ΠΊΠΎΠ΄, ΠΊΠΎΡΠΎΡΡΠΌ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ ΠΏΡΡΠ°Π»ΡΡ ΠΌΠΎΠ½ΠΈΡΠΎΡΠΈΡΡ ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡΠ΅Π»ΡΠ½ΠΎΡΡΡ RAM Π² ΡΠ²ΠΎΠ΅ΠΉ Π²ΠΈΡΡΡΠ°Π»ΡΠ½ΠΎΠΉ ΠΌΠ°ΡΠΈΠ½Π΅. ΠΠΎΠ΄ ΡΡΠΎΡ Ρ ΠΏΡΠΈΠ²ΠΎΠ΄ΠΈΡΡ Π½Π΅ Π±ΡΠ΄Ρ (ΡΠ°ΠΌ Β«ΠΏΠΎΡΡΡΠ½ΠΊΠ°Β») ΠΈ ΠΎΡΡΠ°Π²Π»Ρ ΡΠΎΠ»ΡΠΊΠΎ ΡΠ°ΠΌΠΎΠ΅ ΡΡΡΠ΅ΡΡΠ²Π΅Π½Π½ΠΎΠ΅. ΠΡΠ°ΠΊ, ΠΊΠΎΡ Π² ΡΡΡΠ΄ΠΈΠΈ!
#include <sys/time.h>
#include <string.h>
#include <iostream>
#define CNT 1024
#define SIZE (1024*1024)
int main() {
struct timeval start;
struct timeval end;
long millis;
double gbs;
char ** buffers;
buffers = new char*[CNT];
for (int i=0;i<CNT;i++) {
buffers[i] = new char[SIZE];
}
gettimeofday(&start, NULL);
for (int i=0;i<CNT;i++) {
memset(buffers[i], 0, SIZE);
}
gettimeofday(&end, NULL);
millis = (end.tv_sec - start.tv_sec) * 1000 +
(end.tv_usec - start.tv_usec) / 1000;
gbs = 1000.0 / millis;
std::cout << gbs << " GB/sn";
for (int i=0;i<CNT;i++) {
delete buffers[i];
}
delete buffers;
return 0;
}
ΠΡΡ ΠΏΡΠΎΡΡΠΎ β Π²ΡΠ΄Π΅Π»ΡΠ΅ΠΌ ΠΏΠ°ΠΌΡΡΡ ΠΈ ΠΏΠΈΡΠ΅ΠΌ Π² Π½Π΅Ρ ΠΎΠ΄ΠΈΠ½ Π³ΠΈΠ³Π°Π±Π°ΠΉΡ. Π ΡΡΠΎ ΠΏΠΎΠΊΠ°Π·ΡΠ²Π°Π΅Ρ ΡΡΠΎΡ ΡΠ΅ΡΡ?
$ ./memtest
4.06504 GB/s
ΠΡΠΈΠΌΠ΅ΡΠ½ΠΎ 4GB/s.
Π§ΡΠΎ?!?!
ΠΠ°ΠΊ?!?!?
ΠΡΠΎ Core i7 (ΠΏΡΡΡΡ ΠΈ Π½Π΅ ΡΠ°ΠΌΡΠΉ Π½ΠΎΠ²ΡΠΉ), DDR4, ΠΏΡΠΎΡΠ΅ΡΡΠΎΡ ΠΏΠΎΡΡΠΈ Π½Π΅ Π·Π°Π³ΡΡΠΆΠ΅Π½ β ΠΠΠ§ΠΠΠ£?!?!
ΠΡΠ²Π΅Ρ, ΠΊΠ°ΠΊ Π²ΡΠ΅Π³Π΄Π°, Π½Π΅ΠΎΠ±ΡΠΊΠ½ΠΎΠ²Π΅Π½Π½ΠΎ ΠΎΠ±ΡΠΊΠ½ΠΎΠ²Π΅Π½Π½ΡΠΉ.
ΠΠΏΠ΅ΡΠ°ΡΠΎΡ new (ΠΊΠ°ΠΊ ΠΈ ΡΡΠ½ΠΊΡΠΈΡ malloc, ΠΊΡΡΠ°ΡΠΈ) Π½Π° ΡΠ°ΠΌΠΎΠΌ Π΄Π΅Π»Π΅ Π½Π΅ Π²ΡΠ΄Π΅Π»ΡΠ΅Ρ ΠΏΠ°ΠΌΡΡΡ. ΠΡΠΈ ΡΡΠΎΠΌ Π²ΡΠ·ΠΎΠ²Π΅ Π°Π»Π»ΠΎΠΊΠ°ΡΠΎΡ ΡΠΌΠΎΡΡΠΈΡ ΡΠΏΠΈΡΠΎΠΊ ΡΠ²ΠΎΠ±ΠΎΠ΄Π½ΡΡ ΡΡΠ°ΡΡΠΊΠΎΠ² Π² ΠΏΡΠ»Π΅ ΠΏΠ°ΠΌΡΡΠΈ, ΠΈ Π΅ΡΠ»ΠΈ ΠΈΡ Π½Π΅Ρ, Π²ΡΠ·ΡΠ²Π°Π΅Ρ sbrk() ΡΡΠΎΠ±Ρ ΡΠ²Π΅Π»ΠΈΡΠΈΡΡ ΡΠ΅Π³ΠΌΠ΅Π½Ρ Π΄Π°Π½Π½ΡΡ , ΠΈ Π·Π°ΡΠ΅ΠΌ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅Ρ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ΅ ΡΡΡΠ»ΠΊΡ Π½Π° Π°Π΄ΡΠ΅Ρ ΠΈΠ· Π½ΠΎΠ²ΠΎΠ³ΠΎ ΡΠΎΠ»ΡΠΊΠΎ ΡΡΠΎ Π²ΡΠ΄Π΅Π»Π΅Π½Π½ΠΎΠ³ΠΎ ΡΡΠ°ΡΡΠΊΠ°.
ΠΡΠΎΠ±Π»Π΅ΠΌΠ° Π² ΡΠΎΠΌ, ΡΡΠΎ Π²ΡΠ΄Π΅Π»Π΅Π½Π½ΡΠΉ ΡΡΠ°ΡΡΠΎΠΊ ΡΠ΅Π»ΠΈΠΊΠΎΠΌ Π²ΠΈΡΡΡΠ°Π»ΡΠ½ΡΠΉ. Π Π΅Π°Π»ΡΠ½ΡΠ΅ ΡΡΡΠ°Π½ΠΈΡΡ ΠΏΠ°ΠΌΡΡΠΈ Π½Π΅ Π²ΡΠ΄Π΅Π»Π΅Π½Ρ.
Π ΠΊΠΎΠ³Π΄Π° ΠΏΡΠΎΠΈΡΡ ΠΎΠ΄ΠΈΡ ΠΏΠ΅ΡΠ²ΠΎΠ΅ ΠΎΠ±ΡΠ°ΡΠ΅Π½ΠΈΠ΅ ΠΊ ΠΊΠ°ΠΆΠ΄ΠΎΠΉ ΡΡΡΠ°Π½ΠΈΡΠ΅ ΠΈΠ· ΡΡΠΎΠ³ΠΎ Π²ΡΠ΄Π΅Π»Π΅Π½Π½ΠΎΠ³ΠΎ ΡΠ΅Π³ΠΌΠ΅Π½ΡΠ°, MMU Β«Π²ΡΡΡΡΠ΅Π»ΠΈΠ²Π°Π΅ΡΒ» page fault, ΠΏΠΎΡΠ»Π΅ ΡΠ΅Π³ΠΎ Π²ΠΈΡΡΡΠ°Π»ΡΠ½ΠΎΠΉ ΡΡΡΠ°Π½ΠΈΡΠ΅, ΠΊ ΠΊΠΎΡΠΎΡΠΎΠΉ ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡΡΡ Π΄ΠΎΡΡΡΠΏΠ°, Π½Π°Π·Π½Π°ΡΠ°Π΅ΡΡΡ ΡΠ΅Π°Π»ΡΠ½Π°Ρ.
ΠΠΎΡΡΠΎΠΌΡ Π½Π° ΡΠ°ΠΌΠΎΠΌ Π΄Π΅Π»Π΅ ΠΌΡ ΡΠ΅ΡΡΠΈΡΡΠ΅ΠΌ Π½Π΅ ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡΠ΅Π»ΡΠ½ΠΎΡΡΡ ΡΠΈΠ½Ρ ΠΈ ΠΌΠΎΠ΄ΡΠ»Π΅ΠΉ RAM, Π° ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡΠ΅Π»ΡΠ½ΠΎΡΡΡ MMU ΠΈ VMM ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΎΠ½Π½ΠΎΠΉ ΡΠΈΡΡΠ΅ΠΌΡ. Π Π΄Π»Ρ ΡΠΎΠ³ΠΎ, ΡΡΠΎΠ±Ρ ΡΠ΅ΡΡΠΈΡΠΎΠ²Π°ΡΡ ΡΠ΅Π°Π»ΡΠ½ΡΡ ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡΠ΅Π»ΡΠ½ΠΎΡΡΡ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠ²Π½ΠΎΠΉ ΠΏΠ°ΠΌΡΡΠΈ, Π½Π°ΠΌ Π½ΡΠΆΠ½ΠΎ ΠΏΡΠΎΡΡΠΎ ΠΎΠ΄Π½ΠΎΠΊΡΠ°ΡΠ½ΠΎ ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·ΠΈΡΠΎΠ²Π°ΡΡ Π²ΡΠ΄Π΅Π»Π΅Π½Π½ΡΠ΅ ΡΡΠ°ΡΡΠΊΠΈ. ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ ΡΠ°ΠΊ:
#include <sys/time.h>
#include <string.h>
#include <iostream>
#define CNT 1024
#define SIZE (1024*1024)
int main() {
struct timeval start;
struct timeval end;
long millis;
double gbs;
char ** buffers;
buffers = new char*[CNT];
for (int i=0;i<CNT;i++) {
// FIXED HERE!!!
buffers[i] = new char[SIZE](); // Add brackets, &$# !!!
}
gettimeofday(&start, NULL);
for (int i=0;i<CNT;i++) {
memset(buffers[i], 0, SIZE);
}
gettimeofday(&end, NULL);
millis = (end.tv_sec - start.tv_sec) * 1000 +
(end.tv_usec - start.tv_usec) / 1000;
gbs = 1000.0 / millis;
std::cout << gbs << " GB/sn";
for (int i=0;i<CNT;i++) {
delete buffers[i];
}
delete buffers;
return 0;
}
Π’ΠΎ Π΅ΡΡΡ, ΠΌΡ ΠΏΡΠΎΡΡΠΎ ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·ΠΈΡΡΠ΅ΠΌ Π²ΡΠ΄Π΅Π»ΡΠ΅ΠΌΡΠ΅ Π±ΡΡΠ΅ΡΡ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ΠΌ ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ (char 0).
ΠΡΠΎΠ²Π΅ΡΡΠ΅ΠΌ:
$ ./memtest
28.5714 GB/s
ΠΡΡΠ³ΠΎΠ΅ Π΄Π΅Π»ΠΎ.
ΠΠΎΡΠ°Π»Ρ β Π΅ΡΠ»ΠΈ Π²Π°ΠΌ Π½ΡΠΆΠ½Ρ Π±ΠΎΠ»ΡΡΠΈΠ΅ Π±ΡΡΠ΅ΡΡ ΡΡΠΎΠ±Ρ Π±ΡΡΡΡΠΎ-Π±ΡΡΡΡΠΎ ΡΠ°Π±ΠΎΡΠ°ΡΡ, Π½Π΅ Π·Π°Π±ΡΠ²Π°ΠΉΡΠ΅ ΠΈΡ
ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·ΠΈΡΠΎΠ²Π°ΡΡ.
ΠΡΡΠΎΡΠ½ΠΈΠΊ: habr.com