Π•Ρ‰Π΅ Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ ΠΎ Π½Π΅ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎΠΌ тСстировании

ΠžΠ΄Π½Π°ΠΆΠ΄Ρ‹ ΠΌΠ½Π΅ случайно попался Π½Π° Π³Π»Π°Π·Π° ΠΊΠΎΠ΄, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ пытался ΠΌΠΎΠ½ΠΈΡ‚ΠΎΡ€ΠΈΡ‚ΡŒ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ 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