Как выравнивание и границы страниц влияют на производительность при перемещении и чтении объектовC++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Как выравнивание и границы страниц влияют на производительность при перемещении и чтении объектов

Сообщение Anonymous »

Я провел тест, чтобы лучше понять, как страницы влияют на производительность при перемещении и чтении объектов в памяти, но получил противоположное тому, что ожидал. Я надеюсь, что кто-нибудь сможет объяснить этот странный результат.
Я попробовал создать 600 64-байтовых структур и заполнить их случайными значениями, а затем просмотреть их для суммирования значений.В первом тесте я разместил структуры парами на расстоянии двух страниц друг от друга. Таким образом, все 600 структур умещаются на 300 страницах, например:
Изображение

Во втором тесте я сместил расположение структур так, чтобы все они находились на разных страницах (всего 600), что, как я ожидал, ухудшит производительность:
Изображение

Но по какой-то причине второй тест показал результаты намного лучше, чем первый. Это было почти в два раза быстрее.
Вот исходный код:

Код: Выделить всё

#include 
#include 
#include 
#include 

//64 byte struct (one cache line)
struct test_struct_t {
int data[16]{};
};

int main() {

//your page size is probably 4KB but you
//can get it at runtime like this:
SYSTEM_INFO si;
GetSystemInfo(&si);
const size_t page_size_bytes = si.dwPageSize;

//allocate 650 pages (2600 KB) of page-aligned memory
std::byte* buffer = (std::byte*)_aligned_malloc(
page_size_bytes * 650, page_size_bytes);

//traverse 600 structs for the test
//(using a vector of pointers)
const int no_structs = 600;
std::vector structs;
structs.reserve(no_structs);

//random number generation
std::random_device dev;
std::mt19937 rng(dev());
std::uniform_int_distribution

random(0, 1);

//create 600 structs and give them random values
for (int i = 0; i < no_structs; i++) {

//place the structs in pairs
int pos = (i % 2) * sizeof(test_struct_t)
//and place the pairs 2 pages apart
+ floor(i / 2) * page_size_bytes * 2;

//the buffer of structs will look like this:
//https://i.sstatic.net/9kq53JKN.png

//**** uncomment the line below to perform
//the test with all structs offset so each
//one is on a different page, i.e. like this:
//https://i.sstatic.net/AJQpl1C8.png

//pos += page_size_bytes - sizeof(test_struct_t);

structs.push_back(::new(&buffer[pos])
test_struct_t{ (int)random(rng)});
}

//flush the cache before the test by
//traversing 25mb of random junk data
const size_t junk_size_bytes = 25.0 * 1024.0 * 1024.0;
const int no_ints = junk_size_bytes / sizeof(int);
int* junk_data = (int*)malloc(junk_size_bytes);
if (junk_data == nullptr) exit(-1);
for (int i = 0; i < no_ints; i++) junk_data[i] = random(rng);
int sum_flush = 0;
for (int i = 0; i < no_ints; i++) sum_flush += junk_data[i];
free(junk_data);

//start the test: traverse 600 structs and sum their first value
auto time_start = std::chrono::steady_clock::now();
float sum = 0;
for (auto& str : structs) sum += str->data[0];
auto time_end = std::chrono::steady_clock::now();

//get the execution time
double time_microseconds =
(double)std::chrono::duration_cast
(time_end - time_start).count() / 1000.0;

//print results
std::cout 

Подробнее здесь: [url]https://stackoverflow.com/questions/79387949/how-page-alignment-page-borders-affect-performance-when-traversing-reading-o[/url]
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»