在C语言中高效地使用大型数组

在C语言中高效地使用大型数组,c,arrays,C,Arrays,我正在用C编写一个程序,它使用4D阵列,有200多万个点数。我目前的实施方式如下: main.h extern float data[31][31][25][100]; main.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;

我正在用C编写一个程序,它使用4D阵列,有200多万个点数。我目前的实施方式如下:

main.h

extern float data[31][31][25][100]; 
main.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];
}
谢谢你的帮助

评论回复:

  • 无法以编程方式生成数据。生成数据 离线模拟
  • 我已经更新了代码,以显示数组在主数组之外,并且是全局数组
  • @js1你是对的,它接近9MB,我使用了两个版本的代码,5MB的可执行文件有一百万个以上的元素
  • @pm100我想这是一个很好的问题…我正在一台pc上原型化这段代码,它工作得很好…但它最终将在嵌入式平台上运行。我们目前正计划使用a进行测试(这是一种用于rc车辆的arm板,我们的生产板将更快,并具有更多内存)。我试图尽可能地高效和优化,以缓解在arm平台上运行的任何潜在问题
  • @user3629249是的,我们正在mac osx上原型化我们的代码,然后 一旦我们完成,就为ARM编译
  • @mcleod_ideafix将加载一个包含2百万的二进制文件 你能快点吗?老实说,我甚至没有考虑过二进制文件…我 我将尝试这样实现。每次调用程序时,它都会 将需要访问此数据的某些部分。它不需要所有的2 但输入决定了它需要阵列的哪个部分 它是可变的。理想情况下,我希望只加载阵列的一部分 我需要的。但是,当我尝试时,加载文件并 搜索正确的阵列花费的时间比当前长2-3倍 方法我不知道我年轻时是否把事情搞砸了 正在加载/搜索文件
  • 对评论的回答第二部分: 数据不是稀疏的……我想不出任何简单的方法可以在不降低模型保真度的情况下减少pts的数量。数据是固定的,永远不会改变。将改变的是使用数据的输入,这将导致使用4D数据的不同部分

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


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

    如果您的数据不能通过编程生成,那么当您的程序启动时,它们必须位于硬盘的某个位置,并且您的程序必须以某种方式将数据加载到4D阵列中

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

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


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

    是否需要32位浮点精度? 例如,16位定点值会将二进制文件的大小减半。 如果存储在表中的值的特征是线性的而不是指数的,那么就每存储一位信息的精度而言,定点是存储它们的最有效的方法

    每个值24位或12位的不均匀定点表示也是一种可能性

    也可以考虑使用不同精度的表的不同部分。

    是否实际使用了查找表的每个值?也许可以省略其中的某些小节。它将以更复杂的数据结构和查找功能为代价来减少大小


    另一方面,您可能希望将查找表声明为“const”。

    我建议您在每个列表中使用Tree。这将大大减少到(LOG(n))的查找时间和最多n(LOG(n))的插入时间

    这至少可以帮助您的应用程序在运行时更快地运行


    您需要使用一个合适的数据结构。例如堆或通用B-树。

    你能按程序生成
    数据的内容而不是硬编码它吗?即使我们处理的是像5这样的数字,你重载double的几率也非常高。我对这方面不太了解
    
    ld: can't link with a main executable file 'test' for architecture x86_64