我正在编写一个从命令行获取一系列参数的脚本
script.pl start end
for ($k1=$start; $k1<$end; $k1 += 0.001) {
for ($k2=$start; $k2<$end; $k2 += 0.01) {
for ($k3=$start; $k3<$end; $k3 += 0.001) {
for ($k4=$start; $k4<$end; $k4 += 0.001) {
for ($k5=$start; $k5<$end; $k5 += 0.001) {
...
}}}}}
如果我将参数设置在 0 到 1 之间,则需要很长时间。最简单的方法是将它们分成更小的间隔,例如
script.pl 0 0.01
script.pl 0.01 0.02
...
script.pl 0.9 1
那我要同时打开100个屏幕!!
有人可以指导我如何自动完成吗?
我不确定什么是最好的方法,因此我问了。我有 256 个内核。
最佳答案
查看并行代码时真正关键的问题是依赖性。我将假设 - 因为您的脚本可以分割 - 您不会在循环内做任何复杂的事情。
但是因为你步进了 0.001 和 5 个循环深度,所以如果你要从 0 到 1,你只是做了很多次迭代。准确地说,有 100,000,000,000,000 次。
为了并行化,我个人建议您“展开”外循环并使用 Parallel::ForkManager
.
例如
my $CPU_count = 256;
my $fork_manager = Parallel::ForkManager->new($CPU_count);
for ( my $k1 = $start; $k1 < $end; $k1 += 0.001 ) {
# Run outer loop in parallel
my $pid = $fork_manager->start and next;
for ( my $k2 = $start; $k2 < $end; $k2 += 0.01 ) {
for ( my $k3 = $start; $k3 < $end; $k3 += 0.001 ) {
for ( my $k4 = $start; $k4 < $end; $k4 += 0.001 ) {
for ( my $k5 = $start; $k5 < $end; $k5 += 0.001 ) {
...;
}
}
}
}
$fork_manager->end;
}
这将做的是 - 对于该“外部”循环的每次迭代, fork 您的流程并将 4 个内部循环作为单独的流程运行。它的上限为 256 个并发进程。您应该将其与可用的 CPU 数量相匹配。
但请记住 - 这仅适用于琐碎的“CPU 密集型”任务。如果你正在做大量的磁盘 IO 或试图共享内存,这几乎不会起作用。
另请注意 - 如果外循环上的步骤数少于 CPU 的数量,它就不会很好地并行化。
我还要注意 - $k2
有一个较小的迭代器。我已经从你的源代码中复制了它,但它可能是一个错字。
关于linux - 在多核和并行处理上运行脚本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26128929/