如何在Julia中运行n秒的计算?

如何在Julia中运行n秒的计算?,julia,Julia,我想在Julia中运行固定时间的大量计算,例如10秒。我试过这个: timer = Timer(10.0) while isopen(timer) computation() end 但这不起作用,因为计算永远不会让Julia的任务调度器控制。因此,我在循环中添加了yield(): timer = Timer(10.0) while isopen(timer) yield() computation() end 但是现在调用yield()会带来很大的开销,特别是当调用

我想在Julia中运行固定时间的大量计算,例如10秒。我试过这个:

timer = Timer(10.0)
while isopen(timer)
    computation()
end
但这不起作用,因为计算永远不会让Julia的任务调度器控制。因此,我在循环中添加了
yield()

timer = Timer(10.0)
while isopen(timer)
    yield()
    computation()
end

但是现在调用
yield()
会带来很大的开销,特别是当调用
computation()
很短时。我想我可以每隔1000次左右调用
yield()
isopen()
,但我更喜欢这样一种解决方案,即每次更改计算时不必调整迭代次数。有什么想法吗?

下面的模式使用线程,在我的笔记本电脑上,每1000000次呼叫的延迟约为35毫秒,这是任何工作都无法接受的

在Julia 1.5候选版本上测试:

function should_stop(timeout=10)
    handle = Threads.Atomic{Bool}(false)
    mytask = Threads.@spawn begin
        sleep(timeout)
        Threads.atomic_or!(handle, true)
    end
    handle
end


function do_some_job_with_timeout()
    handle = should_stop(5)
    res = BigInt() # save results to some object
    mytask = Threads.@spawn begin
        for i in 1:10_000_000
            #TODO some complex computations here
            res += 1 # mutate the result object
            handle.value && break
        end
    end
    wait(mytask) # wait for the job to complete
    res
end
您也可以改用
分布式
。下面的代码似乎有更好的延迟-每1000000次超时检查只有1ms左右

using Distributed
using SharedArrays
addprocs(1)
function get_termination_handle(timeout=5,workerid::Int=workers()[end])::SharedArray{Bool}
    handle = SharedArray{Bool}([false])
    proc = @spawnat workerid begin
        sleep(timeout)
        handle[1]=true
    end
    handle
end


function fun_within_timeout()
    res = 0
    h = get_termination_handle(0.1)
    for i = 1:100_000_000
        res += i % 2 == 0 ? 1 : 0
        h[1] && break
    end
    res
end


您是否希望每次执行
计算
所需的时间大致相同?是的,大致相同。谢谢Przemyslaw Szufel,但不幸的是,我无法实现这一点。如果我按原样运行,计算机上的计算将在2秒后完成。如果我将迭代增加到1:10^9,计算不会在5秒后停止。如果我在循环中添加
yield()。我怀疑睡眠和循环任务都安排在同一个线程中。注意,在启动JULIA之前,我确实设置了JULIA_NUM_THREADS=16。还请注意,我尝试在主线程而不是第二个线程中运行作业。@spawn,但没有任何区别。您有什么版本?我一直在Julia 1.5 rc1中测试它。只有当这两个线程是分开的时,这段代码才对我有效(这就是为什么我生成了两次)。您可以尝试添加另一个变量并存储
Threads.threadid()
,以查看它们是否单独生成。据我所知,没有选择threadid的方法,因此如果这没有帮助,我将建议使用
Distributed
。我使用的是1.4.2。我将尝试使用1.5 rc1。我添加了
分布式
代码。它似乎也有更低的延迟。感谢分布式版本,它似乎在Julia 1.4.2中工作。此外,我可以确认,在使用1.5rc1时,第一个解决方案对我有效。然而,分布式版本在1.5rc1中不适用于我,这很奇怪。