Страницы

Поиск по вопросам

понедельник, 15 октября 2018 г.

Массив объектов и массивы свойств объекта, скорость доступа

Здравствуйте. Ниже два примера: в первом создаётся массив объектов со свойствами, во втором создаётся один объект, но на каждое св-во по массиву. Что-то мне подсказывает, что в обоих случаях скорость доступа к данным должна быть одинаковой, но в реальности она отличается и зависит от кол-ва свойств. Подскажите, пожалуйста, есть ли ошибка в медленной версии и, если есть, как сделать правильно. Пример 1, скорость выполнения 300 мс: struct Item { unsigned int p1; unsigned int p2; unsigned int p3; unsigned int p4; unsigned int p5; unsigned int p6; unsigned int p7; unsigned int p8; unsigned int p9; unsigned int p10; };
void main() { cout << "Start" << endl;
clock_t time;
unsigned int itemsAmount = 100000000;
Item *items = new Item[itemsAmount];
for (unsigned int i = 0; i < itemsAmount; i++) { items[i].p1 = 1; }
time = clock();
unsigned int count = 0; for (unsigned int i = 0; i < itemsAmount; i++) { count += items[i].p1; }
cout << (clock() - time) << endl; cout << count << endl;
system("pause"); } Пример 2, скорость выполнения 30 мс: struct Item { unsigned int *p1; unsigned int *p2; unsigned int *p3; unsigned int *p4; unsigned int *p5; unsigned int *p6; unsigned int *p7; unsigned int *p8; unsigned int *p9; unsigned int *p10; };
void main() { cout << "Start" << endl;
clock_t time;
unsigned int itemsAmount = 100000000;
Item *items = new Item; items->p1 = new unsigned int[itemsAmount]; items->p2 = new unsigned int[itemsAmount]; items->p3 = new unsigned int[itemsAmount]; items->p4 = new unsigned int[itemsAmount]; items->p5 = new unsigned int[itemsAmount]; items->p6 = new unsigned int[itemsAmount]; items->p7 = new unsigned int[itemsAmount]; items->p8 = new unsigned int[itemsAmount]; items->p9 = new unsigned int[itemsAmount]; items->p10 = new unsigned int[itemsAmount];
for (unsigned int i = 0; i < itemsAmount; i++) { items->p1[i] = 1; }
time = clock();
unsigned int count = 0; for (unsigned int i = 0; i < itemsAmount; i++) { count += items->p1[i]; }
cout << (clock() - time) << endl; cout << count << endl;
system("pause"); }


Ответ

Это классическая иллюстрация работы кэш-памяти. В первом случае разность адресов двух соседних элементов p1 равна sizeof(Item), во втором случае - sizeof(unsigned int), что в 10 раз меньше. Это означает, что во втором случае при последовательном чтении элементов p1 загрузка в кэш очередного блока памяти будет выполняться реже, что приведет к сокращению времени доступа к данным из этого блока. В вашем случае это дало выигрыш в 10 раз.

Комментариев нет:

Отправить комментарий