首页 文章

使用批处理文件打开多个MATLAB文件实例,这些实例只会压缩cpu 100%

提问于
浏览
0

所以基本上这是一个关于如何更有效地使用多核处理器的问题 .

我有一个优化脚本(用matlab编写),可以调用20个matlab实例来评估函数 . 结果将保存为.mat文件,然后优化脚本将获取这些结果并执行其他一些工作 . 我调用20个matlab实例的方法是首先使用matlab内置函数“system”来调用批处理文件,然后打开20个matlab实例来评估函数 .

我在批处理文件中使用的代码是:

(   start matlab -nosplash -nodesktop -minimize -r "Worker01;exit"
ping -n 5 127.0.0.1 >nul    

start matlab -nosplash -nodesktop -minimize -r "Worker02;exit"
ping -n 5 127.0.0.1 >nul

...... % repeat the pattern 

    start matlab -nosplash -nodesktop -minimize -r "Worker19;exit"
ping -n 5 127.0.0.1 >nul 

start matlab -nosplash -nodesktop -minimize -r "Worker20;exit"
ping -n 5 127.0.0.1 >nul )  | set /P "="

所有“开始”命令都包含在命令后面的括号中

"| set/P"=""

因为我想在完成所有20次评估后继续我的优化脚本 . 我从另一个问题中学到了这个技巧,但我并不真正理解它的真正含义 . 如果你也可以解释一下,我将非常感激 .

无论如何,这是一种在matlab 2007下实现并行计算的方法,该方法没有原始的并行计算功能 . 但是,我发现这不是同时运行20个实例的有效方法,因为在打开12个实例之后,我的cpu(xeon服务器cpu,14个核心可用)使用率达到100% . 我的理论是,打开比cpu更多的实例可能会使处理器效率降低 . 所以我认为最好的策略是这样的:

  • 开始前12个实例;
    一旦当前正在运行的任何实例完成,
  • 就会在列表中启动下一个(s) . (即使 Worker 大致在同一时间开业并做同样的工作,他们仍然倾向于在不同的时间完成 . )

这样可以确保计算能力得到充分利用(CPU使用率始终为100%),而不会过度压缩CPU .

我怎样才能在批处理文件中实现这个策略?如果批处理文件很难实现,那PowerShell可以这样做吗?

请显示实际代码并说明 . 我不是程序员,所以我对编码知之甚少 .

谢谢 .

1 回答

  • 0

    我在powershell中想到这个......

    <#
    keep a queue of all jobs to be executed
    
    keep a list of running jobs
    
    number of running jobs cannot exceed the throttle value
    #>
    
    $throttle = 12
    
    $queue = New-Object System.Collections.Queue
    $running = New-Object System.Collections.Generic.List[System.Diagnostics.Process]
    
    # generate x number of queue commands
    # runs from 1 to x
    1..20 | ForEach-Object {
        # the variable $_ contains the current number
    
        $program = "matlab"
        $args = "-nosplash -nodesktop -minimize -r `"Worker$_;exit`""
    
        # args will be
        # -nosplash -nodesktop -minimize -r "Worker1;exit"
        # -nosplash -nodesktop -minimize -r "Worker2;exit"
        # etc
    
        # save it
        $queue.Enqueue(@($program, $args))
    }
    
    # begin executing jobs
    while($queue.Count) {
        # remove jobs that are done
        $running.Where({ $_.HasExited }) |
            ForEach-Object { [void]$running.Remove($_) }
    
        if($running.Count -ge $throttle) {
            # busy, so wait
            Start-Sleep -Milliseconds 50
        }
        else {
            # ready for new job
            $cmd = $queue.Dequeue()
            [void]$running.Add([System.Diagnostics.Process]::Start($cmd[0], $cmd[1]))
        }
    }
    
    # wait for rest to be done
    while($running.Where({ !$_.HasExited }).Count) {
        Start-Sleep -Milliseconds 50
    }
    

相关问题