Структура массивов и массив структур - разница в производительности
У меня есть такой класс:
//Array of Structures
class Unit
{
public:
float v;
float u;
//And similarly many other variables of float type, upto 10-12 of them.
void update()
{
v+=u;
v=v*i*t;
//And many other equations
}
};
Я создаю массив объектов типа Unit. И позвоните в обновление по ним.
int NUM_UNITS = 10000;
void ProcessUpdate()
{
Unit *units = new Unit[NUM_UNITS];
for(int i = 0; i < NUM_UNITS; i++)
{
units[i].update();
}
}
Чтобы ускорить процесс и, возможно, автоматически векторизовать цикл, я преобразовал AoS в структуру массивов.
//Structure of Arrays:
class Unit
{
public:
Unit(int NUM_UNITS)
{
v = new float[NUM_UNITS];
}
float *v;
float *u;
//Mnay other variables
void update()
{
for(int i = 0; i < NUM_UNITS; i++)
{
v[i]+=u[i];
//Many other equations
}
}
};
Когда цикл не удается автоматически векторизовать, я получаю очень плохую производительность для структуры массивов. Для 50 единиц обновление SoA немного быстрее, чем AoS. Но затем, начиная со 100 единиц, SoA медленнее, чем AoS. В 300 единиц, SoA почти вдвое хуже. На 100 тыс. Единиц SoA в 4 раза медленнее, чем AoS. Хотя кеш может быть проблемой для SoA, я не ожидал, что разница в производительности будет такой высокой. Профилирование на cachegrind показывает одинаковое количество промахов для обоих подходов. Размер объекта Unit составляет 48 байт. Кэш-память L1 - 256 КБ, L2 - 1 МБ, а L3 - 8 МБ. Что мне здесь не хватает? Это действительно проблема с кешем?
Edit: Я использую GCC 4.5.2. Опции компилятора: -o3 -msse4 -ftree-vectorize.
Я сделал еще один эксперимент в СоА. Вместо того, чтобы динамически распределять массивы, я выделял & quot; v & quot; и & quot; u & quot; во время компиляции. При наличии 100 тыс. Блоков это дает производительность, которая в 10 раз выше, чем SoA с динамически размещаемыми массивами. Что тут происходит? Почему существует такая разница в производительности между статической и динамически выделяемой памятью?