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

?v=1

Однажды мне случайно попался на глаза код, которым пользователь пытался мониторить производительность RAM в своей виртуальной машине. Код этот я приводить не буду (там «портянка») и оставлю только самое существенное. Итак, кот в студии!

#include 
#include 
#include 

#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

Всё просто — выделяем память и пишем в неё один гигабайт. И что показывает этот тест?

$ ./memtest
4.06504 GB/s

Примерно 4GB/s.

Что??!!

Как??!?!

Это Core i7 (пусть и не самый новый), DDR4, процессор почти не загружен — ПОЧЕМУ??!!

Ответ, как всегда, необыкновенно обыкновенный.

Оператор new (как и функция malloc, кстати) на самом деле не выделяет память. При этом вызове аллокатор смотрит список свободных участков в пуле памяти, и если их нет, вызывает sbrk () чтобы увеличить сегмент данных, и затем возвращает программе ссылку на адрес из нового только что выделенного участка.

Проблема в том, что выделенный участок целиком виртуальный. Реальные страницы памяти не выделены.

И когда происходит первое обращение к каждой странице из этого выделенного сегмента, MMU «выстреливает» page fault, после чего виртуальной странице, к которой производится доступа, назначается реальная.

Поэтому на самом деле мы тестируем не производительность шины и модулей RAM, а производительность MMU и VMM операционной системы. А для того, чтобы тестировать реальную производительность оперативной памяти, нам нужно просто однократно инициализировать выделенные участки. Например так:

#include 
#include 
#include 

#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

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

Проверяем:

$ ./memtest
28.5714 GB/s

Другое дело.

Мораль — если вам нужны большие буферы чтобы быстро-быстро работать, не забывайте их инициализировать.

© Habrahabr.ru