在过去一周左右的时间里,我一直在重写一大段代码,以使其尽快运行。
该代码正在对衍射激光束进行建模,其本质是一个 640*640 内核在许多 2D 1280*1280 切片上的卷积——每个切片都是沿光束轴的一个新位置。
优化的第一阶段是编译我的函数,第二阶段是学习 Mathematica 喜欢处理大量数据列表——因此一次将多层的 3D 空间传递给它,而不是一个接一个地切片。
然而,这吃了我的内存!
这是我目前的设置:
Func2[K_ , ZRange_] :=
Module[{layers = Dimensions[ZRange][[1]]},
x = ConstantArray[Table[x, {x, -80, 80, 0.125}, {y, -80, 80, 0.125}], {layers}];
y = ConstantArray[Table[y, {x, -80, 80, 0.125}, {y, -80, 80, 0.125}], {layers}];
z = Table[ConstantArray[z, {1281, 1281}], {z, ZRange}];
UTC = Func3[x, y, z];
Abs[ListConvolve[K, #] & /@ UTC]
]
Func3 = Compile[{{x, _Real}, {y, _Real}, {z, _Real}},
Module[{Sr2R2 = Sqrt[x^2 + y^2 + z^2]},
0.5 (1. + z/Sr2R2) Exp[2 \[Pi] I (Sr2R2 - z)]/Sr2R2],
RuntimeAttributes -> {Listable},
CompilationTarget -> "C"
];
ZRangeList = {{20., 19., 18., 17., 16., 15., 14., 13., 12., 11.},
{10., 9., 8., 7., 6., 5., 4., 3., 2., 1.}};
results = Table[Func2[kernel, ZList], {ZList, ZRangeList}];
一些解释:
- 这项工作分为两个功能,因为我希望能够尽可能多地编译。
- Z 值被拆分为列表列表,以使函数一次评估多个层。
一些问题:
- 你会如何让这更快?
- 按原样运行时,我的两个内核都被使用,但由一个mathematica内核使用。如果我使用 ParallelTable 运行它,它会运行多个内核,但会消耗更多的 RAM,最终速度会变慢。
- 我希望能够在尽可能多的内核上运行它——我有一个 LightweightGrid 正在运行——我该怎么做?
- 为什么我不能传递不同维度的编译函数列表?