Pis sınaq haqqında bir az daha

Bir gün təsadüfən istifadəçinin virtual maşınında RAM performansını izləməyə çalışdığı koda rast gəldim. Mən bu kodu verməyəcəyəm (orada "ayaq örtüyü" var) və yalnız ən vacibini buraxacağam. Beləliklə, pişik studiyadadır!

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

Bu sadədir - yaddaş ayırın və ona bir gigabayt yazın. Və bu test nəyi göstərir?

$ ./memtest
4.06504 GB / s

Təxminən 4GB/s.

Nə?!?!

Necə?!?!?

Bu Core i7 (ən yeni olmasa da), DDR4, prosessor demək olar ki, yüklənməyib - NİYƏ?!?!

Cavab, həmişə olduğu kimi, qeyri-adi adidir.

Yeni operator (yeri gəlmişkən, malloc funksiyası kimi) əslində yaddaş ayırmır. Bu çağırışla ayırıcı yaddaş hovuzunda boş yerlərin siyahısına baxır və əgər yoxdursa, məlumat seqmentini artırmaq üçün sbrk() funksiyasını çağırır və sonra proqrama yeni yerdən ünvana istinadı qaytarır. ayrılmışdır.

Problem ondadır ki, ayrılan ərazi tamamilə virtualdır. Həqiqi yaddaş səhifələri ayrılmır.

Və bu ayrılmış seqmentdən hər bir səhifəyə ilk giriş baş verdikdə, MMU səhifə xətasını “vurur”, bundan sonra daxil olan virtual səhifəyə həqiqi səhifə verilir.

Buna görə də, əslində, biz avtobus və RAM modullarının performansını yox, əməliyyat sisteminin MMU və VMM performansını yoxlayırıq. Və RAM-in real işini yoxlamaq üçün sadəcə olaraq ayrılmış sahələri bir dəfə işə salmalıyıq. Məsələn, bu kimi:

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

Yəni, biz sadəcə olaraq ayrılmış buferləri standart dəyərlə işə salırıq (char 0).

Yoxlayırıq:

$ ./memtest
28.5714 GB / s

Başqa bir şey.

Hekayənin əxlaqi - tez işləmək üçün böyük tamponlara ehtiyacınız varsa, onları işə salmağı unutmayın.

Mənbə: www.habr.com

Добавить комментарий