我正在开发一个使用4D阵列的C程序。我目前实现如下:
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];
}
总和是作为占位符...在它的位置将是一个4D查找表的东西。我这样实现,因为我不想从磁盘加载这些数据。在未来我可能会使用数据库或其他东西来加载一部分数据,但现在我需要使用整个数据集。
所以我的问题是......有没有什么方法可以让我更有效率和/或我可以使这个可执行文件更小(可执行文件目前是~5 MB。这最终将在四核手臂板上运行。
我尝试过的唯一一件事就是使用gcc进行优化。我已经尝试了-O2和-O4并且我得到了以下错误。没有-O2,它编译并运行良好。有任何想法吗?我还没有真正查找所有优化选项...只是尝试了我在网上看过的东西。
ld: can't link with a main executable file 'test' for architecture x86_64
感谢您的帮助!
评论的回答:
评论的答案pt2: 数据不稀疏...我想不出任何简单的方法来减少pts的数量而不降低模型的保真度。数据是固定的,永远不会改变。将要改变的是使用数据的输入,这将导致使用4D数据的不同部分。
就数据而言:它实际上是飞行器的轨迹预测数据。使用在群集上运行的非线性模拟离线生成4D数据 所以我的嵌入式程序必须做的是将当前车辆状态(位置,方向等)与4D数据一起生成估计轨迹。由于专有原因,我无法真正提供数据集。我希望这能回答一些问题...抱歉模糊不清
我将处理二进制实现并尝试加载数组的子集。我可能做了一些愚蠢的事情,让它变得非常慢。谢谢大家的评论,它给了我一些新的想法尝试。
答案 0 :(得分:0)
如果无法以编程方式生成数据,那么当程序启动时,它们必须位于硬盘中的某个位置,并且程序必须以某种方式将数据加载到4D阵列中。
因此,如果您的可执行文件大小为5MB,考虑到包含初始化数据,这是正常的。这种方法的好处是可以加载和初始化数组的操作系统。当程序执行main()函数的第一条指令时,数据已经存在。你只需要使用它。缺点是如果你的程序永远不需要使用数据,他们使用的内存仍然存在,浪费地址空间。
另一方面,您可以将数据放在一个单独的文件中:无论是作为处理过程加载的数据文件,还是程序在需要时加载的动态库,或者映射的二进制文件进入记忆。这样做的好处是,只有在需要时才将数据加载到内存中,仅在实际访问数据时需要额外的地址空间,并在不再需要时释放数据。此外,您的可执行文件将加载更快,因为不需要先前的加载和初始化。这样做的缺点是你的程序必须包含一些程序来在使用它之前加载和初始化4D阵列,还有一些程序在不需要时处理它。
也就是说,对于需要为整个程序生存的静态非程序计算值数组,最有效的方法是将数组声明为全局并在同一声明中初始化它。这将在.data部分中添加一个内存块,其中包含已经采用数组所需格式的初始化数据。在重定位操作期间,该内存块的开头将分配给数组的名称。
答案 1 :(得分:0)
您需要32位浮点精度吗? 例如,16位定点值可以将二进制文件的大小减半。 如果表中存储的值的特征是线性的而不是指数的,那么固定点是以每个存储的信息位的精度存储它们的最有效方式。
每个值24位或12位的不均匀定点表示也是可能的。
您还可以考虑对表格的不同部分使用不同的精度级别。
是否实际使用了查找表的每个值?也许可以省略它的某些子部分。它将以更复杂的数据结构和查找功能为代价来减小尺寸。
另外,您可能希望将查找表声明为“const”。
答案 2 :(得分:0)
就你的查询而言。
我建议您为每个列表使用Tree&#39; s。这将大大减少查询时间(LOG(n))和插入时间以及最多n(log(n))。
这至少可以帮助您的应用程序在运行时更快地移动。
您希望使用体面的数据结构。例如堆或通用B-TREE。