Arhn - архитектура программирования

Стоимость доступа к динамически созданным объектам с динамически выделенными элементами

Я создаю приложение, которое будет иметь динамически выделенные объекты типа A, каждый из которых имеет динамически выделенный член (v), аналогичный приведенному ниже классу.

class A {
int a;
int b;
int* v;
};

куда:

  • Память для v будет выделена в конструкторе.
  • v будет выделен один раз при создании объекта типа A, и никогда не потребуется изменять его размер.
  • Размер v будет варьироваться для всех экземпляров A.

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

  • Может ли динамическое выделение v означать, что экземпляр A и его элемент v не находятся в памяти вместе?
  • Какие инструменты и методы можно использовать для проверки того, является ли эта фрагментация узким местом в производительности?
  • Если такая фрагментация является проблемой производительности, существуют ли какие-либо методы, позволяющие A и v размещаться в непрерывной области памяти?
  • Или существуют какие-либо методы для облегчения доступа к памяти, такие как схема предварительной выборки? например, получить объект типа A, работающий с другими переменными-членами при предварительной выборке v.
  • Если бы размер v или допустимый максимальный размер мог быть известен во время компиляции, приведет ли замена v массивом фиксированного размера, например int v[max_length], к лучшей производительности?

Целевыми платформами являются стандартные настольные компьютеры с процессорами x86/AMD64, ОС Windows или Linux, скомпилированные с использованием компиляторов GCC или MSVC.


Ответы:


1

Если у вас есть веская причина заботиться о производительности...

Может ли динамическое выделение v означать, что экземпляр A и его элемент v не находятся в памяти вместе?

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

Если экземпляр A находится в стеке, маловероятно, что его 'v' будет поблизости.

Если такая фрагментация является проблемой производительности, существуют ли какие-либо методы, позволяющие A и v размещаться в непрерывной области памяти?

Выделите место для обоих, а затем поместите их в это пространство. Это грязно, но обычно должно работать:

char* p = reinterpret_cast<char*>(malloc(sizeof(A) + sizeof(A::v)));
char* v = p + sizeof(A);
A* a = new (p) A(v);

// time passes

a->~A();
free(a);

Или существуют какие-либо методы для облегчения доступа к памяти, такие как схема предварительной выборки?

Предварительная выборка зависит от компилятора и платформы, но многие компиляторы имеют для этого встроенные функции. Имейте в виду - это не очень поможет, если вы попытаетесь получить доступ к этим данным сразу, поскольку предварительная выборка может иметь какое-либо значение, вам часто нужно делать это за сотни циклов, прежде чем вам нужны данные. Тем не менее, это может дать огромный прирост скорости. Встроенная функция будет выглядеть примерно так: __pf(my_a->v);

Если бы размер v или допустимый максимальный размер мог быть известен во время компиляции, приведет ли замена v массивом фиксированного размера, например int v[max_length], к лучшей производительности?

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

Специфика зависит от того, каковы ваши цели дизайна и производительности. Интересное обсуждение этого вопроса с «реальной» конкретной проблемой на конкретном оборудовании с конкретным компилятором см. в Подводные камни объектно-ориентированного программирования (это ссылка в Документах Google для PDF-файла, сам PDF-файл можно найти здесь).

26.05.2010
  • Аккуратный. Я не знал о размещении новых. 26.05.2010
  • Если они оба выделены «новым», то вполне вероятно, что они будут рядом друг с другом - нет. Если A — 16 байт, а v — 512 КБ, маловероятно, что они окажутся рядом друг с другом. И -1 за предложение грязных хаков, не зная, действительно ли это нужно ОП. 26.05.2010
  • С другой стороны, если sizeof(v)=512 КБ, то не так важно, примыкают ли к ним 16 байтов A. И совместное выделение пространства — это не грязный хак. Обычно вы оборачиваете его в член статического класса (идиома общедоступного имени ctor). 26.05.2010
  • @Kornel - без дополнительной информации от ОП, как мы узнаем, что ищет ОП. Предложение вариантов перед лицом неполной информации является основной практикой SO, тем более, когда OP специально запрашивает расширенные методы. Извините, что вы обижены моим комментарием к вашему сообщению, но единственное неверное утверждение относительно программирования - абсолютное. 26.05.2010

  • 2

    Может ли динамическое выделение v означать, что экземпляр A и его элемент v не находятся в памяти вместе?

    Да, это будет скорее всего.

    Какие инструменты и методы можно использовать для проверки того, является ли эта фрагментация узким местом в производительности?

    кешгринд, акула.

    Если такая фрагментация является проблемой производительности, существуют ли какие-либо методы, позволяющие A и v размещаться в непрерывной области памяти?

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

    Или существуют какие-либо методы для облегчения доступа к памяти, такие как схема предварительной выборки? например, получить объект типа A, работающий с другими переменными-членами при предварительной выборке v.

    Да, вы могли бы сделать это. Лучше всего было бы разместить области памяти, используемые вместе, рядом друг с другом.

    Если бы размер v или допустимый максимальный размер мог быть известен во время компиляции, приведет ли замена v массивом фиксированного размера, например int v[max_length], к лучшей производительности?

    Может быть, а может и нет. По крайней мере, это сделало бы v локальной для членов структуры.

    1. Напишите код.
    2. Профиль
    3. Оптимизировать.
    26.05.2010

    3

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

    Не могли бы вы просто иметь одну копию структуры и один (большой) буфер v, прочитать в него свои данные (в двоичном формате, для скорости), сделать очень небольшой расчет и перейти к следующему.

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

    26.05.2010
    Новые материалы

    Коллекции публикаций по глубокому обучению
    Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

    Представляем: Pepita
    Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

    Советы по коду Laravel #2
    1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

    Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
    Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

    3 способа решить квадратное уравнение (3-й мой любимый) -
    1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

    Создание VR-миров с A-Frame
    Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

    Демистификация рекурсии
    КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..