Это своего рода вопрос, связанный с этим оригинальным вопросом с добавлением новой информации. См. Здесь для первой части, если вам интересно: Struct of arrays, arrays of structs and memory usage patternСтруктура массивов и шаблоны доступа к памяти
Кажется, что с моей первой попыткой настройки структуры массивов для простого класса существует немало проблем. В основном это избыточное выделение памяти для указателей и возможные утечки памяти из выделения этих указателей из vec3_b в предыдущем вопросе.
Я, хотя о том, как я мог изменить данные без использования указателей, для этого требуется, чтобы я сначала установил некоторую константную переменную для размера моих ведра данных, поэтому неограниченные значения, такие как указатели, а также уменьшают объем памяти до что-то исправленное.
const size_t batch_size = 100;
struct vec3_c
{
size_t x[batch_size];
size_t y[batch_size];
size_t z[batch_size];
};
struct vec3_c vec3_c(size_t x, size_t y, size_t z, size_t index)
{
struct vec3_c v;
v.x[index] = x;
v.y[index] = y;
v.z[index] = z;
return v;
}
struct vec3_c vc3;
for(int i = 0; i < batch_size; i++)
{
vc3 = vec3_c(i+1, i*i, i*10, i);
//printf("vec3c x:%zu, y:%zu, z:%zu\n",vc3.x[i], vc3.y[i], vc3.z[i]);
printf("vec3c x:%p, y:%p, z:%p\n",(void*)&vc3.x[i], (void*)&vc3.y[i], (void*)&vc3.z[i]);
}
---------------x-----------------|----------------y-----------------|----------------z-----------------|
0| 0x7fff57489f40 : 140734657765184 | 0x7fff5748a260 : 140734657765984 | 0x7fff5748a580 : 140734657766784
1| 0x7fff57489f48 : 140734657765192 | 0x7fff5748a268 : 140734657765992 | 0x7fff5748a588 : 140734657766792
2| 0x7fff57489f50 : 140734657765200 | 0x7fff5748a270 : 140734657766000 | 0x7fff5748a590 : 140734657766800
с этим обновленным кодом, я должен иметь фиксированный размер ведра, так что я установить его на batch_size 100 только для простых чисел. Заполните vec3c некоторыми данными и выполните аналогичный тест, на этот раз кажется, что каждое значение выровнено в 8 байтовых кусках.
например:
size of vec3 : 24 bytes
size of vec3a : 24 bytes
size of vec3b : 24 bytes
size of vec3c : 2400 bytes
size of size_t : 8 bytes
size of int : 4 bytes
size of 16 int : 64 bytes
vec3c x:0x7fff592d2f40, y:0x7fff592d3260, z:0x7fff592d3580
vec3c x:0x7fff592d2f48, y:0x7fff592d3268, z:0x7fff592d3588
vec3c x:0x7fff592d2f50, y:0x7fff592d3270, z:0x7fff592d3590
vec3c x:0x7fff592d2f58, y:0x7fff592d3278, z:0x7fff592d3598
vec3c x:0x7fff592d2f60, y:0x7fff592d3280, z:0x7fff592d35a0
vec3c x:0x7fff592d2f68, y:0x7fff592d3288, z:0x7fff592d35a8
vec3c x:0x7fff592d2f70, y:0x7fff592d3290, z:0x7fff592d35b0
vec3c x:0x7fff592d2f78, y:0x7fff592d3298, z:0x7fff592d35b8
vec3c x:0x7fff592d2f80, y:0x7fff592d32a0, z:0x7fff592d35c0
vec3c x:0x7fff592d2f88, y:0x7fff592d32a8, z:0x7fff592d35c8
все разделены на 8 байт.
Это должно избавиться от проблем утечки памяти и избыточной памяти, необходимой для указателей.
с этим новым расположением что-то вроде sizeof (vc3 [0] .x) вернет 8 байтов.
обратно в исходные вопросы:
Является ли моя реализация
struct vec3_c
правильный способ установки на структуру массива?с размером партии vec_3c, равным 100, он показывает 2400 байт, но каждый отдельный элемент имеет всего 8 байтов и правильно выровнен, поэтому я мог бы теперь поместить 8 элементов в 1 линию современного кэша процессора?
будет преобразовывать данные, переданные мне, например, типичный формат только массивов структур перевешивает преимущества производительности в состоянии, совместимом с кэшем, и способен работать с несколькими точками данных на вызов команды? Это связано с тем, что обе точки 1 и 2 являются правильными.
ех делает скалярное произведение двух векторов: , что означает, что я мог бы получить скалярное произведение 2 vec3_c за один цикл инструкции?
редактировать еще один вопрос, было бы лучше, чтобы добавить дополнительные 8 байт данных, чтобы сделать эту структуру кратны 32 байта и, возможно, использовать дополнительные 8 байты как рабочее пространство или просто оставить его пустым?
Редактировать Было указано, что моя первоначальная функция инициализации просто путала вещи.Я обновил его к этой форме:
struct vec3_c* vec3_c()
{
struct vec3_c *v = (struct vec3_c*)malloc(sizeof(struct vec3_c));
v->index = 0;
return v;
}
struct vec3_c* v3 = vec3_c();
for(size_t i = 0; i < batch_size; i++)
{
v3->x[i] = i + 1;
v3->y[i] = i * i;
v3->z[i] = i * 10;
printf("index:%d\tvec3c x:%zu, y:%zu, z:%zu\n",i,v3->x[i], v3->y[i], v3->z[i]);
printf("index:%zu\tvec3c x:%p, y:%p, z:%p\n",i,(void*)&v3->x[i], (void*)&v3->y[i], (void*)&v3->z[i]);
}
Извините, возможно, я неправильно истолковал всю проблему, но мне кажется, что вы используете vc3 v v неправильно: действительно, функция vec3_c выделяет локальный (неинициализированный) «v», затем устанавливает НЕКОТОРЫЕ поля и возвращает COPY OF v (поля которого содержат непредсказуемые значения, кроме «индексного»). Я вижу, что в вашем примере вас действительно не интересует содержимое vc3, так что же является целью функции vec3_c? –
@GiuseppeGuerrini В моем примере исходного кода было несколько ошибок, которые я со временем выяснил. Я бы использовал эту структуру для пакетного процесса. Vec3 что-то значает как обработку потока или инструкции типа SIMD. – user1610950