gpt4 book ai didi

c - 在 C 中有效地使用大型数组

转载 作者:太空宇宙 更新时间:2023-11-04 04:37:25 24 4
gpt4 key购买 nike

我正在使用 C 编写一个程序,该程序使用具有 200 万多个点的 4D 数组。我目前是这样实现的:

主.h

extern float data[31][31][25][100]; 

主.c

float data[31][31][25][100] = {{.....},{......},.....}; 

int main()
{
double sum;

for(i=0;i<31;i++)
for(j=0;j<31;j++)
for(k=0;k<25;k++)
for(l=0;l<100;l++)
sum += data[i][j][k][l];
}

总和作为占位符存在...取而代之的是一个 4D 查找表。我这样实现是因为我不想从磁盘加载这些数据。将来我可能会使用数据库或其他东西来加载一部分数据,但现在我需要使用整个数据集。

所以我的问题是......有什么办法可以更有效地实现这一点和/或我可以使这个可执行文件更小吗(当前可执行文件约为 5 MB。这最终将在四核臂板上运行。

我唯一尝试过的另一件事是使用 gcc 进行优化。我试过 -O2 和 -O4,但出现以下错误。没有 -O2,它编译并运行良好。有任何想法吗?我还没有真正查看所有优化选项是什么...只是尝试了我在网上看到的东西。

ld: can't link with a main executable file 'test' for architecture x86_64

感谢您的帮助!

回复评论:

  1. 无法以编程方式生成数据。数据生成通过离线模拟
  2. 我已更新代码以显示数组在主数组之外并且是全局的
  3. @js1 你是对的,它接近 9 MB,我正在处理几个版本的代码,而 5 MB 的可执行文件是一个包含 100 万多个元素的文件。
  4. @pm100 我想这是一个很好的问题……我正在个人电脑上制作这段代码的原型(prototype),它运行良好……但它最终将在嵌入式平台上运行。我们目前正计划使用 pixhawk 进行测试(这是遥控车的臂板,我们的生产板会更快,内存更大)。我正在努力尽可能高效和优化,以减轻在 arm 平台上运行的任何潜在问题。
  5. @user3629249 是的,我们正在 mac osx 上制作我们的代码原型(prototype),然后完成后为 ARM 编译。
  6. @mcleod_ideafix 将加载包含 200 万的二进制文件点更快?老实说,我什至没有考虑过二进制文件……我将尝试像这样实现。每次程序被调用时,它将需要访问此数据的某些部分。它不需要全部 2百万点,但输入决定它需要数组的哪一部分是可变的。理想情况下,我只想加载数组的一部分我需要的。然而,当我尝试它时,加载文件并搜索正确的阵列所花的时间比当前的长 2-3 倍方法。我想知道我是不是搞砸了什么加载/搜索文件。

评论 pt2 的回答:数据不稀疏……我想不出任何简单的方法来减少点数而不降低模型的保真度。数据是固定的,永远不会改变。将改变的是使用数据的输入,这将导致使用 4D 数据的不同部分。

就数据是什么而言:它本质上是飞行器的轨迹预测数据。 4D 数据是使用在集群上运行的非线性模拟离线生成的。
所以我的嵌入式程序要做的是将当前车辆状态(位置、方向等)与 4D 数据一起生成估计轨迹。由于专有原因,我无法真正提供数据集。我希望这能回答一些问题...抱歉含糊不清

我将致力于二进制实现并尝试加载数组的一个子集。我可能做了一些愚蠢的事情,让它变得很慢。谢谢大家的评论,它给了我一些新的想法来尝试。

最佳答案

如果您的数据无法以编程方式生成,那么当您的程序启动时,它们必须位于您硬盘中的某个位置,并且您的程序必须以某种方式将该数据加载到 4 维数组中。

因此,如果您的可执行文件大小为 5MB,考虑到包含初始化数据,这是正常的。这种方法的好处是作为加载和初始化阵列的操作系统。当您的程序执行 main() 函数的第一条指令时,数据已经存在。你只需要使用它。缺点是如果你的程序永远不需要使用数据,它们使用的内存仍然存在,浪费地址空间。

另一方面,您可以将数据放在单独的文件中:无论是作为处理的一部分加载的数据文件,还是程序在需要时加载的动态库,或者映射的二进制文件进入内存。这样做的好处是,只有在需要时才将数据加载到内存中,只有在实际访问数据时才需要额外的地址空间,并在不再需要时释放它。此外,您的可执行文件将加载得更快,因为不需要预先加载和初始化。这样做的缺点是您的程序必须包含一些过程以在使用 4D 数组之前加载和初始化它,以及一些其他过程以在不需要时处理它。

也就是说,对于需要在整个程序中存在的静态非过程计算值数组,最有效的方法是将数组声明为全局数组并在同一声明中对其进行初始化。这将在您的 .data 部分中添加一个带有初始化数据的内存块,该数据已经采用数组所需的格式。在重定位操作期间,该内存块的开头将分配给您的数组名称。

关于c - 在 C 中有效地使用大型数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29569813/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com