Nim:具有变异状态的并行循环

时间:2017-10-23 23:39:25

标签: concurrency pass-by-reference nim

我是Nim语言的新手。我想通过实现一个简单的遗传算法来学习它,通过将工作分配到CPU核心来演化字符串(整数atm数组):

https://github.com/peheje/nim_genetic

我已经成功并行化了“代理”的创建,但是不能这样做来调用必须改变传入状态的函数“生命”:

...

type
Agent* = ref object
    data*: seq[int]
    fitness*: float

...
var pool: seq[Agent] = newAgentsParallel(POPULATION_SIZE)
# Run generations
for gen in 0..<N_GENERATIONS:
    let wheel = createWheel(pool)
    let partitions: seq[seq[Agent]] = partition(pool, N_THREADS)
    parallel:
        for part in partitions:
            echo "spawning"
            spawn life(part, pool, wheel)
    pool = createPool(pool, wheel)
...
proc life(part: seq[Agent], pool: seq[Agent], wheel: seq[float]) =
for a in part:
    if random(1.0) < CROSSOVER_PROP:
        a.crossover(pool, wheel)
    if random(1.0) < MUTATE_PROP:
        a.mutate()
    a.calcFitness()
echo "life done"

CPU受到100%的约束,看起来Nim正在将数据复制到“生命”,因为“生成”后RAM使用量猛增。在Nim手册中,它描述了并行块:

  

“生成的proc中使用的每个其他复杂位置loc   (spawn f(loc))在并行期间必须是不可变的   部分。这称为不变性检查。目前它不是   指定究竟“复杂位置”的含义。我们需要做到这一点   优化!“

而且我非常喜欢它作为可变状态,所以也许这就是Nim复制数据的原因?我怎样才能绕过传递指针?几点:

  • 我想我可以避免变异,而是返回修改过的新实例,但我仍然需要传入池中并转向读取。
  • 如果无法使用parallel:语句,我将如何使用线程实现它?
  • 随机()线程安全吗?怎么回事?
  • 我还能做些什么吗?例如。更容易展开FlowVar?

来自Kotlin和Java8 Streams,我感觉很糟糕。

0 个答案:

没有答案