使用 Matlab 编码器动态和静态分配的正确方法是什么?
What is the right way to work with Matlab coder dynamic and static allocations?
我最近开始使用 Matlab coder 来构建计算机视觉算法。我正在研究点云 class化问题,这意味着我的算法输入是一组 3D 点 (x,y,z),而我的输出是具有 class 化 3D 点的变量数组.
对于这个项目,我决定使用 Matlab 编码器。 Coder 要求开发人员指定内存分配的上限。那么问题来了——输入的 3D 点集最多可以有 250k 个点,每个 class 的输出约为 50k 个点。除此之外,我的实现分配的 3D 网格大小最大为:600x600x120 (uint8) 和我使用的一些辅助内存。我的意思是我正在处理大内存分配。
我尝试使用静态分配;然而,感觉 Matlab 还没有为每个内存分配大约 1mb 的情况构建静态内存分配。
我将内存上限设置为较大的值,然后使用Coder生成C++代码并编译。我第一次 运行 算法有堆栈溢出,然后我不得不将堆栈大小扩大到 30mb(在 visual studio 内),这被认为是荒谬的。
另一方面,我可以使用动态内存分配。然而在这种情况下,几乎所有的东西都会被动态分配,这也是一个令人头疼的问题,因为大量的分配和取消分配耗时。
我希望从 Matlab 中编写一个代码,在其实现内部保存上限内存,该上限内存不会在算法的多次迭代之间发生变化。 (就像 C++ 中的成员 classes)
我会更具体:如果我的算法使用 600x600x120 的网格和几个大小为 600x600 的图像,我希望 Matlab Coder 将生成只分配这些内存一次的代码,我会使用它们在不同的算法迭代上。
我有几个问题:
如何在算法的不同迭代之间使用连续的内存分配。 (如何避免每次迭代分配和取消分配)
我应该为静态内存分配设置多少合适的堆栈大小(静态分配 1mb 是否合理?)
我考虑过在这种情况下使用全局内存。行得通吗?
有什么解决问题的建议吗?
谢谢
我最终使用了默认的堆栈限制,我将动态内存分配阈值(在编码器应用程序中:内存 --> 动态内存分配阈值)扩展到一个很大的限制(~50MB)。
然后我设置生成可重入代码(在编码器应用程序中:内存 --> 生成可重入代码)
这是我从 Matlab 得到的 answer:
有两种推荐的方法可以避免在算法的多次迭代中使用大量堆栈和动态分配。
对于两者,将 Stack Space Usage 设置得足够小以防止局部变量适合堆栈。
选项 A:使用堆栈 space 设置。这将强制这些变量具有 "static" 存储 class。这些在程序启动时分配一次,并且在每次调用算法时重复使用相同的内存。
选项B,除了堆栈space设置外,开启MultiInstanceCode。这不是静态局部变量,而是创建一个类型,其中包含对于堆栈来说太大的所有可能的局部变量。在调用算法之前,分配一次space,并在每次调用算法时将其传递给生成的C++函数。
局部变量是否分配到栈上可以通过Stack Space Usage setting来控制,它设置了栈大小的限制。
如果不在堆栈上,变量通常会"spilled"作为静态局部变量,在程序初始化时分配一次。但是,启用 Re-entrant Code setting 允许一次性动态分配大内存(而不是静态局部变量)。
更多细节请看我在相应MATLAB Answers上的回答post:
我最近开始使用 Matlab coder 来构建计算机视觉算法。我正在研究点云 class化问题,这意味着我的算法输入是一组 3D 点 (x,y,z),而我的输出是具有 class 化 3D 点的变量数组.
对于这个项目,我决定使用 Matlab 编码器。 Coder 要求开发人员指定内存分配的上限。那么问题来了——输入的 3D 点集最多可以有 250k 个点,每个 class 的输出约为 50k 个点。除此之外,我的实现分配的 3D 网格大小最大为:600x600x120 (uint8) 和我使用的一些辅助内存。我的意思是我正在处理大内存分配。
我尝试使用静态分配;然而,感觉 Matlab 还没有为每个内存分配大约 1mb 的情况构建静态内存分配。 我将内存上限设置为较大的值,然后使用Coder生成C++代码并编译。我第一次 运行 算法有堆栈溢出,然后我不得不将堆栈大小扩大到 30mb(在 visual studio 内),这被认为是荒谬的。
另一方面,我可以使用动态内存分配。然而在这种情况下,几乎所有的东西都会被动态分配,这也是一个令人头疼的问题,因为大量的分配和取消分配耗时。 我希望从 Matlab 中编写一个代码,在其实现内部保存上限内存,该上限内存不会在算法的多次迭代之间发生变化。 (就像 C++ 中的成员 classes)
我会更具体:如果我的算法使用 600x600x120 的网格和几个大小为 600x600 的图像,我希望 Matlab Coder 将生成只分配这些内存一次的代码,我会使用它们在不同的算法迭代上。
我有几个问题:
如何在算法的不同迭代之间使用连续的内存分配。 (如何避免每次迭代分配和取消分配)
我应该为静态内存分配设置多少合适的堆栈大小(静态分配 1mb 是否合理?)
我考虑过在这种情况下使用全局内存。行得通吗?
有什么解决问题的建议吗? 谢谢
我最终使用了默认的堆栈限制,我将动态内存分配阈值(在编码器应用程序中:内存 --> 动态内存分配阈值)扩展到一个很大的限制(~50MB)。 然后我设置生成可重入代码(在编码器应用程序中:内存 --> 生成可重入代码)
这是我从 Matlab 得到的 answer:
有两种推荐的方法可以避免在算法的多次迭代中使用大量堆栈和动态分配。
对于两者,将 Stack Space Usage 设置得足够小以防止局部变量适合堆栈。 选项 A:使用堆栈 space 设置。这将强制这些变量具有 "static" 存储 class。这些在程序启动时分配一次,并且在每次调用算法时重复使用相同的内存。
选项B,除了堆栈space设置外,开启MultiInstanceCode。这不是静态局部变量,而是创建一个类型,其中包含对于堆栈来说太大的所有可能的局部变量。在调用算法之前,分配一次space,并在每次调用算法时将其传递给生成的C++函数。
局部变量是否分配到栈上可以通过Stack Space Usage setting来控制,它设置了栈大小的限制。
如果不在堆栈上,变量通常会"spilled"作为静态局部变量,在程序初始化时分配一次。但是,启用 Re-entrant Code setting 允许一次性动态分配大内存(而不是静态局部变量)。
更多细节请看我在相应MATLAB Answers上的回答post: