Natuke veel halva testimise kohta

Ühel päeval leidsin kogemata koodi, mille abil kasutaja üritas oma virtuaalmasinas RAM-i jõudlust jälgida. Ma ei anna seda koodi (seal on jalalapp) ja jätan ainult kõige hädavajalikuma. Niisiis, kass on stuudios!

#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;
}

See on lihtne – eraldage mälu ja kirjutage sinna üks gigabait. Ja mida see test näitab?

$ ./memtest
4.06504 GB / s

Umbes 4 GB/s.

Mida?!?!

Kuidas?!?!?

See on Core i7 (ehkki mitte uusim), DDR4, protsessor on peaaegu laadimata - MIKS?!?!

Vastus, nagu alati, on ebatavaliselt tavaline.

Uus operaator (nagu muide funktsioon malloc) tegelikult mälu ei eralda. Selle kõne puhul vaatab jaotaja mälukogu vabade asukohtade loendit ja kui neid pole, kutsub andmesegmendi suurendamiseks käsku sbrk() ja tagastab seejärel programmile viite uuest asukohast pärit aadressile. eraldatud.

Probleem on selles, et eraldatud ala on täielikult virtuaalne. Päris mälulehti ei eraldata.

Ja kui sellel eraldatud segmendil toimub esimene juurdepääs igale lehele, siis MMU "tulistab" lehe tõrke, misjärel määratakse juurdepääsetavale virtuaalsele lehele tõeline.

Seetõttu ei testi me tegelikult siini- ja RAM-moodulite, vaid operatsioonisüsteemi MMU ja VMM-i jõudlust. Ja selleks, et testida RAM-i tegelikku jõudlust, peame eraldatud alad üks kord lähtestama. Näiteks nii:

#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;
}

See tähendab, et me lihtsalt lähtestame eraldatud puhvrid vaikeväärtusega (char 0).

Kontrollime:

$ ./memtest
28.5714 GB / s

Teine asi.

Loo moraal – kui vajate kiireks töötamiseks suuri puhvreid, ärge unustage neid lähtestada.

Allikas: www.habr.com

Lisa kommentaar