Недавно я читал о AoS и SoA проектировании структуры и ориентированном на данные дизайне. Странно трудно найти информацию о них, и то, что я обнаружил, похоже, предполагает лучшее понимание функциональности процессора, чем у меня есть. Тем не менее, то, что я понимаю относительно предыдущей темы, в частности, приводит к некоторым вопросам, на которые, как мне кажется, я смогу понять ответы.
Во-первых, чтобы убедиться, что я не основываю свое понимание на ложной предпосылке, мое понимание функциональных возможностей и преимуществ и недостатков AoS против SoA применительно к набору записей "Персона" с полями "Имя" и "Возраст" связано с ними:
Структура массивов
- Хранит данные в виде единой структуры, состоящей из нескольких массивов, например, в виде объекта
People
с полямиNames
в виде массива строк иAges
в виде массива целых чисел. -
People.Names[2]
информация для третьего лица в списке будет предоставлена чем-то вродеPeople.Names[2]
иPeople.Ages[2]
- Плюсы:
- При работе только с некоторыми данными из множества записей "Персона", только эти данные должны быть загружены из памяти.
- Указанные данные хранятся однородным образом, что позволяет лучше использовать кэш в инструкциях SIMD в большинстве таких ситуаций.
- Минусы: - Когда нужно получить доступ к нескольким полям одновременно, вышеуказанные преимущества исчезают. - Доступ ко всем данным для одного или нескольких объектов становится менее эффективным. - Большинство языков программирования требуют гораздо более многословного и сложного для чтения/записи кода, поскольку нет явной структуры "Персона".
Массив структур
- Хранит данные в виде нескольких структур, каждая из которых имеет полный набор полей, которые сами хранятся в массиве всех таких структур, например, в массиве
People
объектовPerson
, которые имеютName
в качестве строкового поля иAge
в качестве целочисленного поля. - Информация для третьего лица будет предоставлена чем-то вроде
People[2].Name
иPeople[2].Age
- Плюсы:
- Код структурирован вокруг более простой ментальной модели с отвлеченным косвенным влиянием.
- Отдельные записи легко доступны и работают с ними.
- Наличие структуры
Person
делает написание кода на большинстве языков программирования намного проще.
- Минусы:
- При работе только с некоторыми данными из большого количества записей необходимо загрузить в память весь набор структур, включая нерелевантные данные.
- Массив структур не является однородным, что в таких ситуациях ограничивает преимущество, которое может быть обеспечено инструкциями SIMD.
По большому счету кажется, что если исходить из соображений, что узким местом для производительности является доступ к данным, а простота кодирования не имеет значения, если вам почти исключительно необходим доступ к одному полю за раз на большом количестве SoA данных, вероятно, будет более производительным, в то время как если вам часто требуется доступ к нескольким полям одного и того же объекта или иметь дело с отдельными объектами, а не со многими одновременно, AoS будет более производительным.
Тем не менее, кое-что из того, что я читал, кажется, запутало картину. Во-первых, несколько источников заявили, что SoA требует индексированной адресации, которая считается неэффективной. Я не могу понять это, и не смог найти никаких объяснений. Мне кажется, что AoS и SoA требуют одинаковых операций для доступа к любому конкретному фрагменту данных, хотя и в разном порядке, за исключением того, что SoA требует дополнительного указателя (возможно, более одного, в зависимости от используемой структуры). Немного упрощая, чтобы получить возраст пятого человека в моем примере выше под AoS, вы сначала получите указатель на массив, добавите 4 к нему, получите указатель структуры на этот элемент массива, добавите размер строковый указатель на него, поскольку возраст - это второе поле, затем получите доступ к целому числу по этому указателю. В SoA вы получите указатель на структуру и добавите к ней размер указателя массива строк, чтобы получить список возрастов, затем получите указатель на список целых чисел, хранящихся там, и добавите к нему 4, а затем получите целое число хранится там.
Во-вторых, мне неясно, в какой степени преимущества SoA зависят от конкретной архитектуры ЦП. С одной стороны, то, что я понимаю о преимуществах, описанных выше, не зависит от какой-либо конкретной архитектуры, за исключением того, что инструкции SIMD могут обеспечить дополнительные преимущества, недоступные в AoS в некоторых случаях. С другой стороны, я видел заявления о том, что преимущества SoA могут быть ограничены в зависимости от количества полос, доступных в конкретной архитектуре SIMD. Опять же, это может повлиять только на дополнительное преимущество, которое могут дать инструкции SIMD, по сравнению с более общим преимуществом кэша.
Наконец, я видел утверждение, что SoA может требовать больше способов кэширования при обходе данных. Я не совсем уверен, что такое способы кэширования или что, если вообще что-то, подразумевается под "обходом" данных. Мое лучшее предположение состоит в том, что "пути кеширования" относятся либо к числу потенциальных коллизий в ассоциативном кеше, либо коррелируют с ним, и что это относится ко второму Con, упомянутому выше.