如何以缓存友好的方式访问灵活数组的数组?
我有灵活的阵列成员的records
typedef struct record {
unsigned foo;
signed bar;
double number[];
} record;
我有多个records
与同量的numbers
,所以我可以在阵列排列。 我想将它们分配到一个连续的内存空间中。
const unsigned numbers = ...;
const unsigned records = ...;
const size_t record_size = sizeof(record) + numbers*sizeof(double);
record *prec = malloc(records*record_size);
所以现在我知道了record_size
并且我可以访问它,但是如何通过给定record
索引来正确安全地执行它,最佳实践是什么?
我可以做到这一点,当我分开包含foo
和bar
和numbers
,但我想保持record
在一起的缓存一致性。
由于只有你知道实际的布局,所以C编译器不能帮你。 因此,您必须自己进行地址计算。 它需要一些强制转换来在字节级执行指针运算:
record * get_record(record *base, size_t numbers, size_t index)
{
return (record *) ((unsigned char *) base +
index * (sizeof *base + numbers * sizeof *base->number));
}
鉴于上述(和你的代码); 你可以像这样访问数组:
record *first = get_record(base, numbers, 0);
first->foo = 4711;
record *second = get_record(base, numbers, 1);
second->foo = 17;
一个明显的缺点是你将不得不保持numbers
值。 这可以通过使用明确的“基本”结构对整个数组进行建模来进行改进,该结构保存每个元素的大小和基指针。 当然,它可以与元素本身共同分配,以将它们保持在一起并减少所涉及的指针的距离。
另外,请不要在C中返回malloc()
的返回值。
上一篇: How to access array of flexible arrays in cache friendly manner?