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

Posted

技术标签:

【中文标题】哪种使用 C 数组的数据组织可以生成最快的代码,为啥?【英文标题】:Which kind of data organization using C arrays makes fastest code and why?哪种使用 C 数组的数据组织可以生成最快的代码,为什么? 【发布时间】:2011-03-16 09:20:45 【问题描述】:

鉴于以下数据,组织元素数组的最佳方法是什么,以便可能实现最快的随机访问?

每个元素都有一个 int 数字、一个以 '\0' 结尾的 3 个字符的名称和一个浮点值

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

第一:

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 指令数量?

【问题讨论】:

你对SIZE 的定义在我看来是假的。什么意思? @Jens:我的错字,应该是 VALS 【参考方案1】:

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

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

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

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

【讨论】:

我希望以后每个元素都有更多的属性,所以我更喜欢二维数组。 @psihodelia:根据需要声明更多数组有什么问题?此外,如果您要存储的下一个内容不适合四个字节怎么办? 让二维数组的使用变慢? @psihodelia:你在考虑整个性能问题。二维阵列与多个一维阵列中的随机访问之间的差异可以忽略不计。如果您甚至可以测量差异,我会感到惊讶,如果可以,如果 2-D 出现较慢,我一点也不感到惊讶。 ...重申一下,当涉及到低级性能时,缓存利用率是一个更为重要的考虑因素。【参考方案2】:

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

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

【讨论】:

【参考方案3】:

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

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

当然,大多数时候您不必担心这些事情(过早的优化等等)。

【讨论】:

@Jim:我最近收到了很多这样的问题 - 我不知道我是否冒犯了某人,或者这是否只是随机的“开车”投票,但有点无论哪种方式都很烦人。 无论如何都是不道德的行为。

以上是关于哪种使用 C 数组的数据组织可以生成最快的代码,为啥?的主要内容,如果未能解决你的问题,请参考以下文章

cuda 求最大值哪种方式最快

1亿条数据批量插入 MySQL,哪种方式最快

在 C/C++ 中获得正模的最快方法

numpy数组最快的保存和加载选项

在各类算法中那种算法排序是最快的?

哪种 BouncyCastle API 支持的加密算法对于 C# .NET 中的短字符串加密最快且非常安全?