Еще немного о неправильном тестировании

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Прежде чем перейти к статье, хочу вам представить, экономическую онлайн игру Brave Knights, в которой вы можете играть и зарабатывать. Регистируйтесь, играйте и зарабатывайте!

Однажды мне случайно попался на глаза код, которым пользователь пытался мониторить производительность 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/s\n";
	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/s\n";
	for (int i=0;i<CNT;i++) {
		delete buffers[i];
	}
	delete buffers;
	return 0;
}

То есть, мы просто инициализируем выделяемые буферы значением по умолчанию (char 0).

Проверяем:

$ ./memtest
28.5714 GB/s


Другое дело.

Мораль — если вам нужны большие буферы чтобы быстро-быстро работать, не забывайте их инициализировать.
Источник: https://habr.com/ru/post/487248/


Интересные статьи

Интересные статьи

Нередко при работе с Bitrix24 REST API возникает необходимость быстро получить содержимое определенных полей всех элементов какого-то списка (например, лидов). Традиционн...
Недавно на проекте интегрировал модуль CRM Битрикса c виртуальной АТС Ростелеком. Делал по стандартной инструкции, где пошагово показано, какие поля заполнять. Оказалось, следование ей не гаран...
Рекурсия — очень мощный и удобный механизм, если над связанными данными делаются одни и те же действия «вглубь». Но неконтролируемая рекурсия — зло, которое может приводить или к беск...
Тренировочный центр для бортпроводников. Видно надувной трап, модель такого же трапа в виде плота для бассейна. И напротив всего этого сауна. Потому что в Финляндии не могут построить бассейн ...
Компании переполнили рынок товаров и услуг предложениями. Разнообразие наблюдается не только в офлайне, но и в интернете. Достаточно вбить в поисковик любой запрос, чтобы получить подтверждение насыще...