Zaidi kidogo juu ya majaribio mabaya

Siku moja nilipata msimbo kwa bahati mbaya kwamba mtumiaji alikuwa akijaribu kufuatilia utendaji wa RAM kwenye mashine yake ya kawaida. Sitatoa nambari hii (kuna "kitambaa cha miguu" hapo) na nitaacha tu muhimu zaidi. Kwa hiyo, paka iko kwenye studio!

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

Ni rahisi - kutenga kumbukumbu na kuandika gigabyte moja ndani yake. Na mtihani huu unaonyesha nini?

$ ./memtest
4.06504 GB / s

Takriban 4GB/s.

Nini?!?!

Vipi?!?!?

Hii ni Core i7 (ingawa sio mpya zaidi), DDR4, processor karibu haijapakiwa - KWA NINI?!?!

Jibu, kama kawaida, ni la kawaida sana.

Opereta mpya (kama kazi ya malloc, kwa njia) haigawi kumbukumbu. Kwa simu hii, mtoaji anaangalia orodha ya maeneo ya bure kwenye bwawa la kumbukumbu, na ikiwa hakuna, huita sbrk() ili kuongeza sehemu ya data, na kisha inarudisha kwenye programu rejeleo la anwani kutoka eneo jipya tu. zilizotengwa.

Shida ni kwamba eneo lililotengwa ni la kawaida kabisa. Hakuna kurasa halisi za kumbukumbu zilizotengwa.

Na wakati ufikiaji wa kwanza kwa kila ukurasa kutoka kwa sehemu hii iliyotengwa unatokea, MMU "hupiga" kosa la ukurasa, baada ya hapo ukurasa wa kawaida unaopatikana hupewa moja halisi.

Kwa hiyo, kwa kweli, hatujaribu utendaji wa moduli za basi na RAM, lakini utendaji wa MMU na VMM ya mfumo wa uendeshaji. Na ili kupima utendaji halisi wa RAM, tunahitaji tu kuanzisha maeneo yaliyotengwa mara moja. Kwa mfano kama hii:

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

Hiyo ni, tunaanzisha tu bafa zilizotengwa na thamani chaguo-msingi (char 0).

Tunaangalia:

$ ./memtest
28.5714 GB / s

Jambo lingine.

Maadili ya hadithi - ikiwa unahitaji buffers kubwa kufanya kazi haraka, usisahau kuzianzisha.

Chanzo: mapenzi.com

Kuongeza maoni