Что означает локальность структуры данных?

Я читал следующую статью,

Что Каждый Программист Должен Знать Про Оптимизации Компилятора

есть и другие важные оптимизации, которые в настоящее время не возможности любого компилятора-например, замена неэффективного алгоритм с эффективным, или изменение компоновки данных структура для улучшения своей местности.

означает ли это, что я изменяю последовательность (планировка) членов данных в классе, это может повлиять на производительность?

и

class One
{
int data0;
abstract-data-type data1;
};

отличается по производительности от,

class One
{
abstract-data-type data0;
int data1;
};

Если это правда, что такое эмпирическое правило при определении классов или структуры данных?

3 ответов


населенного пункта в этом смысле говорит в основном к кэша. Написание структур данных и алгоритмов для работы в основном из кэша делает алгоритм работать так быстро, как это возможно. Кэша является одной из причин быстрая сортировка быстро.

для структуры данных вы хотите сохранить части структуры данных, которые ссылаются друг на друга относительно близко друг к другу, чтобы избежать промывки полезного кэша русло.

кроме того, вы можете изменить структуру данных так, чтобы компилятор использовал минимальный объем памяти, необходимый для хранения всех членов и эффективного доступа к ним. Это помогает убедиться, что структура данных потребляет минимальное количество строк кэша.

одна строка кэша в текущей архитектуре x86-64 (core i7) составляет 64 байта.


Я не эксперт по локальности данных / структуры, но это связано с тем, как вы организуете свои данные, чтобы избежать кэширования бит памяти процессора со всего процессора, таким образом, замедляя вашу программу, постоянно ожидая выборки памяти.

например, связанный список может быть разбросан по всей вашей памяти. Однако, если вы изменили это на массив" элементов", то все они находятся в непрерывной памяти - это сэкономит время доступа к памяти, Если вам нужно пересечь их массив все в одно время (это только один пример)

дополнительно: Также из-за некоторых библиотек STL, опять же, я не уверен на 100%, какие из них лучшие, но некоторые из них (например, список) довольно плохие с точки зрения локальности. Другим, возможно, более распространенным примером является массив указателей, где указываемые элементы могут быть разбросаны по памяти. Конечно, вы не всегда можете избежать этого легко, потому что иногда вам нужно иметь возможность динамически добавлять / перемещать / вставлять/удалять элементы...

резюме: Это в основном означает, что вы заботитесь о том, как вы размещаете свои данные в отношении доступа к памяти.


сортировка членов класса по тому, как часто вы будете получать к ним доступ. Это максимизирует "горячность" строки кэша, содержащей голову вашего класса, увеличивая вероятность того, что она останется кэшированной. Другим фактором, который вас волнует, является упаковка-из-за выравнивания, перестановка порядка, в котором объявляются члены, может привести к уменьшению размера вашего класса, что, в свою очередь, уменьшит давление кэша.

(ни один из них не окончательный, конечно. Эти правила большой палец не заменяет профилирование.)