使用C数组的哪种数据组织可以生成最快的代码?为什么?

根据以下数据,组织元素数组的最佳方法是什么,以便最快的随机访问?

每个元素都有一些int数,一个名称为3个字符,末尾带有’\ 0’,浮点值

我看到两种可能的方法来组织和访问这样的数组:

第一:

typedef struct { int num; char name[4]; float val; } t_Element; t_Element array[900000000]; //random access: num = array[i].num; name = array[i].name; val = array[i].val; //sequential access: some_cycle: num = array[i].num i++; 

第二:

 #define NUMS 0 #define NAMES 1 #define VALS 2 #define SIZE (VALS+1) int array[SIZE][900000000]; //random access: num = array[NUMS][i]; name = (char*) array[NAMES][i]; val = (float) array[VALS][i]; //sequential access: p_array_nums = &array[NUMS][i]; some_cycle: num = *p_array_nums; p_array_nums++; 

我的问题是,什么方法更快,为什么? 我的第一个想法是第二种方法制作最快的代码,并允许最快的块复制,但我怀疑它是否与第一种方法相比,是否保存了任何敏感数量的CPU指令?

这取决于常见的访问模式。 如果您计划迭代数据,随时访问每个元素, struct方法会更好。 如果您计划在每个组件上独立迭代,那么并行数组会更好。

这也不是一个微妙的区别。 由于主存储器通常比L1高速缓存慢约两个数量级,因此使用适合于使用模式的数据结构可能会使性能提高三倍。

但是,我必须说,实现并行数组的方法还有很多不足之处。 你应该简单地声明三个数组,而不是使用二维数组和转换“聪明”:

 int nums[900000000]; char names[900000000][4]; float vals[900000000]; 

不可能说。 与任何与性能相关的测试一样,答案可能因您的操作系统,CPU,内存,编译器等中的任何一个或多个而异。

所以你需要自己测试一下。 设定您的绩效目标,衡量,优化,重复。

第一个可能更快,因为内存访问延迟将是性能的主要因素。 理想情况下,您应该按顺序连续访问内存,以充分利用已加载的缓存行并减少缓存未命中。

当然,访问模式在任何此类讨论中都是至关重要的,这就是为什么有时最好使用SoA(数组结构)和其他时间AoS(结构数组),至少在性能至关重要时。

当然,大部分时间你都不应该担心这些事情(过早优化,以及所有这些)。