Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Matlab上增加Mex的文件大小_Matlab_Size_Mex - Fatal编程技术网

在Matlab上增加Mex的文件大小

在Matlab上增加Mex的文件大小,matlab,size,mex,Matlab,Size,Mex,我正在用MatlabR2019A编写一个FORTRAN mex文件。我用小数组测试了代码,一切正常。然而,当我尝试增加数组的大小时,我得到了以下错误 致命错误LNK1248:图像大小(9B993000)超过最大允许大小(80000000) 我在windows 10上使用Visual Studio 2017和英特尔FORTRAN编译器,我有16GB的RAM。 这个链接似乎有解决方案,但我似乎在VS2017中找不到链接器选项来传递堆数组 有人能告诉我如何增加尺寸吗 多谢各位 基南 与堆相比,堆栈的

我正在用MatlabR2019A编写一个FORTRAN mex文件。我用小数组测试了代码,一切正常。然而,当我尝试增加数组的大小时,我得到了以下错误

致命错误LNK1248:图像大小(9B993000)超过最大允许大小(80000000)

我在windows 10上使用Visual Studio 2017和英特尔FORTRAN编译器,我有16GB的RAM。 这个链接似乎有解决方案,但我似乎在VS2017中找不到链接器选项来传递堆数组

有人能告诉我如何增加尺寸吗

多谢各位 基南


与堆相比,堆栈的内存量相对较小。堆栈是一个固定数量的内存,基本上是程序的一部分。它用于在例程之间传递参数、局部变量内存等。由于它的大小相对较小,您不应该创建可能溢出堆栈的大型局部变量。这在任何语言中都是正确的,不仅仅是Fortran语言。因此,创建如下局部变量:

real*8 dualfail(30000000)
导致dualfail内存来自堆栈

对于大型变量,更好的方法是从堆中为它们分配内存,堆本质上是整个计算机的主内存。例如:

real*8, allocatable :: dualfail(:)
integer alloc_stat
allocate(dualfail(30000000),stat=alloc_stat)
if( alloc_stat /= 0 ) then
    ! allocation failed, so take action here
endif
! code to use dualfail here
deallocate(dualfail)
所有的大变量都应该使用这种技术

话虽如此,在mex例程中包含这些大变量的唯一原因似乎是为了复制body()例程的MATLAB输入和输出。这是一种非常低效的管理方式。您还深度复制了输出变量,这些变量仅为0,尽管我猜它们无论如何都会被body()覆盖。与其采用这种方法,尤其是在处理大变量时,不如简单地将内存中的“指针”传递给例程。一种方法是使用%VAL()构造。这将首先消除创建这些大型局部变量的需要。例如:

  call body(%VAL(coord_pr),%VAL(dualnumfam_pr),%VAL(dualfail_pr), etc.
因此,在传递MATLAB变量数据副本的任何地方,都会将“指针”(实际上是通过值传递整数中包含的地址)传递到MATLAB变量的原始数据区域。只要您的body()例程将matlabprhs()输入视为只读,那么它就可以工作,而不需要像您这样进行深度复制。这样就不需要所有这些mxCopyReal8ToPtr()和mxCopyPtrToReal8()调用

请注意,我对上面“指针”一词的使用是泛指。。。这些不是Fortran指针变量。但使用实际的Fortran指针将是避免深层数据拷贝的另一种方法。。。i、 例如,将mxGetPr()返回的整数转换为常规Fortran指针,然后在代码的下游使用该指针

我还要指出,您的mex例程严重缺乏输入参数检查。您只检查输入的数量,并且第一个输入是数字。你应该做的是检查你的每一个输入都是双重的、非复杂的、非稀疏的,并且大小正确。因为它是不健全的例行程序,你是在风险得到错误的结果或崩溃的MATLAB如果输入不完全如预期


最后,请注意,出于某种原因,Mathworks选择将/fixed选项硬编码到Fortran mex构建文件中。我已经要求他们删除这个,但截至R2020a它仍然存在。这迫使编译器将所有文件视为固定格式,即使是以.f90结尾的文件。我的建议是在系统中查找这些xml构建文件,并从这些文件中删除/fixed选项。这样,您就可以自然地将.f90文件编译为自由格式。

不要编写使用从堆栈中分配的非常大的局部变量的代码。然后,您总是需要找到正确的编译器/链接器设置来增加堆栈大小或从堆中分配它们。相反,编写代码以使用来自堆的大变量的可分配变量。这应该可以在不尝试查找magic编译器/链接器设置的情况下工作。如果你给我们看一些代码,我们可以建议修改。谢谢James,我读到fortran mex文件不允许分配变量。除了计算例程之外,我已经添加了所有代码。这通常是由于编译器默认为固定格式,这样类似Fortran 90+的代码将导致编译错误。尝试设置,您应该能够使用现代语法和可分配数组编写代码。可能还需要指定一个标准。您在哪里读到Fortran mex文件不允许分配变量?
  call body(%VAL(coord_pr),%VAL(dualnumfam_pr),%VAL(dualfail_pr), etc.