我是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复制数据的原因?我怎样才能绕过传递指针?几点:
来自Kotlin和Java8 Streams,我感觉很糟糕。