Недавно я читал о структуре структуры AoS и SoA и дизайн, ориентированный на данные. Странно трудно найти информацию о том и другом, и то, что я нашел, похоже, предполагает большее понимание функциональности процессора, чем у меня есть. Тем не менее, то, что я действительно понимаю в предыдущей теме, в частности, приводит к некоторым вопросам, на которые, я думаю, я должен быть в состоянии понять ответы.
Во-первых, чтобы убедиться, что я не основываю свое понимание на ложной предпосылке, мое понимание функциональности и плюсов и минусов AoS против SoA применительно к набору записей «Лицо» с полями «Имя» и «Возраст». связанные с ними:
Структура массивов
- Сохраняет данные в виде единой структуры, состоящей из нескольких массивов, например, в виде объекта
People
с полямиNames
в виде массива строк иAges
в виде массива целых чисел. - Информация, скажем, для третьего человека в списке будет предоставлена чем-то вроде
People.Names[2]
иPeople.Ages[2]
. - Pros:
- When working with only some of the data from many 'Person' records, only that data needs to be loaded from memory.
- Упомянутые данные хранятся однородным образом, что позволяет лучше использовать кэш SIMD-инструкциями в большинстве таких ситуаций.
- Минусы: - Когда необходимо получить доступ к нескольким полям одновременно, вышеуказанные преимущества исчезают. - Доступ ко всем данным для одного или нескольких объектов становится менее эффективным. - Большинство языков программирования требуют гораздо более подробного и трудного для чтения/записи кода, поскольку в нем нет явной структуры «Person».
Массив структур
- Хранит данные в виде нескольких структур, каждая из которых имеет полный набор полей, которые сами хранятся в массиве всех таких структур, например массив
People
изPerson
объектов, у которыхName
является строковым полем, аAge
— целочисленным полем. - Информация для третьего лица будет предоставлена чем-то вроде
People[2].Name
иPeople[2].Age
- Pros:
- Code is structured around a simpler mental model, with the indirection being abstracted away.
- Отдельные записи легко доступны и с ними легко работать.
- Наличие структуры
Person
значительно упрощает написание кода на большинстве языков программирования.
- Cons:
- When working with just some of the data from a large number of records, the entire set of structures needs to be loaded into memory including the irrelevant data.
- Массив структур неоднороден, что в таких ситуациях ограничивает преимущество, которое могут дать SIMD-инструкции.
Суть в том, что если предположить ради аргумента, что вашим узким местом для производительности является доступ к данным, а простота кодирования не имеет значения, если вам почти исключительно нужно получить доступ к одному полю за раз на большом количестве Data SoA, вероятно, будет более производительным, в то время как если вам часто нужно обращаться к нескольким полям одного и того же объекта или иметь дело с отдельными объектами, а не со многими одновременно, AoS будет более производительным.
Тем не менее, кое-что из того, что я читал, кажется, искажает картину. Во-первых, несколько источников заявляют, что SoA требует индексированной адресации, которая считается неэффективной. Я не могу понять этого и не могу найти никаких объяснений. Мне кажется, что AoS и SoA требуют одних и тех же операций для доступа к любому конкретному фрагменту данных, хотя и в разном порядке, за исключением того, что SoA требует дополнительного указателя (возможно, более одного, в зависимости от типа используемой структуры). Немного упрощая, чтобы получить возраст пятого человека в моем примере выше в AoS, вы должны сначала получить указатель на массив, добавить к нему 4, получить указатель структуры на этот элемент массива, добавить размер строковый указатель на него, поскольку возраст является вторым полем, а затем получить доступ к целому числу по этому указателю. В SoA вы должны получить указатель на структуру и добавить к ней размер указателя массива строк, чтобы получить список возрастов, затем получить указатель на список целых чисел, хранящихся там, и добавить к нему 4, затем получить целое число, хранящееся там.
Во-вторых, мне не ясно, в какой степени преимущества SoA зависят от конкретных архитектур ЦП. С одной стороны, то, что я понимаю о преимуществах, описанных выше, не зависит от какой-либо конкретной архитектуры, за исключением того, что инструкции SIMD могут предоставлять дополнительные преимущества, недоступные в AoS в некоторых случаях. С другой стороны, я видел заявления о том, что преимущества SoA могут быть ограничены в зависимости от количества линий, доступных в конкретной архитектуре SIMD. Опять же, это, по-видимому, влияет только на дополнительное преимущество, которое инструкции SIMD могут обеспечить по сравнению с более общим преимуществом кэширования.
Наконец, я видел утверждение, что SoA может потребовать больше способов кэширования при обходе данных. Я не совсем уверен, что такое кэш-пути или что конкретно подразумевается под «обходом» данных. Мое лучшее предположение состоит в том, что «пути кеширования» либо относятся к числу потенциальных коллизий в ассоциативном кеше, либо коррелируют с ними, и что они связаны со вторым Con, о котором я упоминал выше.