නරක පරීක්ෂණය ගැන තව ටිකක්

දිනක් මම අහම්බෙන් දුටුවේ පරිශීලකයෙකු ඔහුගේ අතථ්‍ය යන්ත්‍රයේ 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, ප්‍රොසෙසරය පාහේ පටවා නැත - ඇයි?!?!

පිළිතුර, සෑම විටම මෙන්, අසාමාන්ය ලෙස සාමාන්ය ය.

නව ක්‍රියාකරු (malloc ශ්‍රිතය වැනි) ඇත්ත වශයෙන්ම මතකය වෙන් නොකරයි. මෙම ඇමතුම සමඟ, වෙන් කරන්නා මතක තටාකයේ ඇති නිදහස් ස්ථාන ලැයිස්තුව දෙස බලයි, කිසිවක් නොමැති නම්, දත්ත ඛණ්ඩය වැඩි කිරීමට sbrk() අමතා, නව ස්ථානයෙන් ලිපිනය වෙත යොමු කිරීමක් වැඩසටහනට ආපසු එයි. වෙන් කර ඇත.

ගැටළුව වන්නේ වෙන් කරන ලද ප්රදේශය සම්පූර්ණයෙන්ම අථත්ය වීමයි. සැබෑ මතක පිටු වෙන් කර නැත.

මෙම වෙන් කළ කොටසෙන් එක් එක් පිටුවට පළමු ප්‍රවේශය සිදු වූ විට, MMU පිටුවේ දෝෂයක් "වෙඩි" කරයි, ඉන් පසුව ප්‍රවේශ වන අතථ්‍ය පිටුවට සැබෑ එකක් පවරනු ලැබේ.

එබැවින්, ඇත්ත වශයෙන්ම, අපි බසයේ සහ RAM මොඩියුලවල ක්රියාකාරිත්වය නොව, මෙහෙයුම් පද්ධතියේ MMU සහ VMM වල ක්රියාකාරිත්වය පරීක්ෂා කරමු. 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++) {
                // 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

වෙනත් දෙයක්.

කතාවේ සදාචාරය - ඔබට ඉක්මනින් වැඩ කිරීමට විශාල බෆර අවශ්‍ය නම්, ඒවා ආරම්භ කිරීමට අමතක නොකරන්න.

මූලාශ්රය: www.habr.com

අදහස් එක් කරන්න