我目前需要使用Julia中的Cuba库来计算一些三维积分。实际上,我需要在一次运行中多次使用cuhre函数。但是,这存在大量分配的问题。
例如,我可以尝试积分f(x1,x2,x3)= x1 * x2 * x3,这给了我结果(当我使用@time快速查看性能时)

julia> @time cuhre((x,f)->f[1]=x[1]*x[2]*x[3],3,1)
0.101907 seconds (115.82 k allocations: 5.809 MiB)
Component:
1: 0.125 ± 1.5700924586837752e-16 (prob.: 0.0)
Integrand evaluations: 381
Number of subregions:  2
Note: The desired accuracy was reached
问题在于分配只能加起来,这意味着我可以很快达到数以百万计的分配数和GiB的数。由于Julia似乎没有释放内存的方法,因此我仔细查看了Cuba.jl包,发现它包装了C库Cuba(使用ccall)。我看了一下代码(The cuhre part in the C labrary),发现它永远不会释放分配的内存。更准确地说,我看到了(在Integrate.c中)
RuleAlloc(t);

FrameAlloc(t, Master);

MemAlloc(cur, poolsize);
指向指针
This *t
Pool *cur = NULL, *pool;
但是,唯一似乎释放内存的情况是发生异常终止时:
abort:
  while( (pool = cur) ) {
    cur = cur->next;
    free(pool);
  }
  FrameFree(t, Master);
  RuleFree(t);

  StateRemove(t);

  return fail;
但是当程序运行平稳时它永远不会运行。
因此,我考虑过手动修改此功能并添加内存以释放自己,并git-cloned了the cuba library。但是,我正在努力编译最新版本(4.1)。我试图按照给出的(很少)说明进行操作,即键入
$ ./configure
$ ./makeshared.sh #
但是第二个不起作用
$ ./makeshared.sh #
bash: ./makeshared.sh: Aucun fichier ou dossier de ce type
(没有此类型的文件夹的文件)。我寻找解决方案并找到this topic,并尝试给出各种答案(运行demo-c.c文件),但似乎没有任何效果,主要是因为文件中不再存在libcuba.a文件。
因为这有帮助,所以这是编译demo-c.c文件时遇到的错误
$ gcc -o demo-c.exe demo-c.c -lm
/tmp/ccAYMLVk.o : Dans la fonction « main » :
demo-c.c:(.text+0x123) : référence indéfinie vers « Vegas »
demo-c.c:(.text+0x226) : référence indéfinie vers « Suave »
demo-c.c:(.text+0x343) : référence indéfinie vers « Divonne »
demo-c.c:(.text+0x439) : référence indéfinie vers « Cuhre »
collect2: error: ld returned 1 exit status
(对...的 undefined reference )。在1.1版中,这是通过使用以下命令解决的
gcc -o demo-c.exe demo-c.c ../libcuba.a -lm
但由于不再存在此类文件,因此它显然不再起作用。

最佳答案

一般来说,如果您对Cuba C库有任何疑问,最好的办法是与作者联系:https://wwwth.mpp.mpg.de/members/hahn/。如果问题在上游得到解决,则最终将其包含在 Cuba.jl Julia包装器中。

了解由于以下几种原因而使您的内存分配问题放错了位置:

  • 您没有正确执行基准测试: BenchmarkTools.jl 软件包提供了更准确,更可靠的基准测试工具:
    julia> using Cuba, BenchmarkTools
    
    julia> @time cuhre((x,f)->f[1]=x[1]*x[2]*x[3],3,1);
      0.055585 seconds (105.25 k allocations: 5.375 MiB)
    
    julia> @btime cuhre((x,f)->f[1]=x[1]*x[2]*x[3],3,1);
      37.067 μs (1527 allocations: 71.72 KiB)
    
    这比您想的要小两个数量级。
  • @time@btime宏都在Julia端测量内存分配,而不是可以调用的C库的内存分配,因此您看到的内存分配不是来自Cuba库。
  • ,您说的是内存分配的总和,但这并非完全正确:因为每次调用积分函数所分配的内存最终都会被释放。

  • 如果实际上从实践上来说 cuhre 中的Cuba.jl的性能对您来说是个问题(我很少遇到),我强烈建议您研究 HCubature.jl 包:它完全用Julia编写,实现了与cuhre中的Cuba.jl相同的算法,并允许您使用 StaticArrays.jl ,在处理小尺寸(小于约16个元素)时,它比标准数组具有更高的内存效率。

    关于c - 编译古巴图书馆,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/65529326/

    10-11 19:12