2014-02-27 34 views
0

由于​​是下来了,我想我会问这个在这里...并行鼠尾草黄金一代

我试图并行一堆用圣人random_prime函数随机素数的产生。这里有一些代码:

#!/usr/bin/env sage -python 
from __future__ import print_function 
from sage.all import * 
import time 

N = 100 
B = 200 
length = (1 << B) - 1 

print('Generating primes (sequentially)') 
start = time.time() 
ps = [] 
for _ in xrange(N): 
    ps.append(random_prime(length)) 
end = time.time() 
print('Took: %f seconds' % (end - start)) 
print(ps) 

@parallel(ncpus=10) 
def _random_prime(length): 
    return random_prime(length) 

print('Generating primes (in parallel)') 
start = time.time() 
ps = [length] * N 
ps = list(_random_prime(ps)) 
end = time.time() 
print('Took: %f seconds' % (end - start)) 
ps = [p for _, p in ps] 
print(ps) 

第一次运行通过计算素数顺序,它的工作原理。

第二次运行通过使用贤者的@parallel修饰器计算它们。它在计算是并行化的意义上是“有效的”,但所有输出素数都是相同的(即它不会生成100个随机素数,而是100个相同的随机素数)。我认为这是@parallel的常见用例,但我无法找到有关此问题的详细信息。有人有主意吗?谢谢。

回答

1

只是一个暗示 - 这是否有可能你需要设置一个不同的种子每次?请注意,the doc在测试中没有#random,所以也许所有并行实例的种子由于某种原因是相同的(这似乎是合理的)。

编辑把沃尔克的是如何做到这一点更详细的描述:

import os 
import sage.misc.randstate as randstate 
randstate.set_random_seed(os.getpid()) 
+0

是啊,看起来像这样的作品。顺便说一下,你的'#random'回答代表什么? – user2211937

+1

@parallel装饰器使用fork,所以每个并行进程都是执行进程的精确副本。您需要更改每个进程中的种子(在_random_prime中): import os; import sage.misc.randstate as randstate; randstate.set_random_seed(os.getpid()) – vbraun

+0

'#random'是一个注释Sage放入了被测试的代码,以表明输出每次都会改变,并且是“随机”的,因为它不应该被测试每次完全一样。所以如果缺少了,我们预计它每次测试都会一样(在这种情况下,每次都使用相同的种子)。 – kcrisman