是否可以在进程(由多处理创建)之间共享gmpy2 multiprecision整数(https://pypi.python.org/pypi/gmpy2)而无需在内存中创建副本? 每个整数大约有750,000位。整数不会被进程修改。
谢谢。
答案 0 :(得分:0)
更新:经过测试的代码如下。
我会尝试以下未经测试的方法:
使用Python的mmap
库创建内存映射文件。
使用gmpy2.to_binary()
将gmpy2.mpz
实例转换为二进制字符串。
将二进制字符串和二进制字符串本身的长度写入内存映射文件。为了允许随机访问,您应该以固定值的倍数开始每次写入,例如94000。
使用您的所有值填充内存映射文件。
然后在每个进程中,使用gmpy2.from_binary()
从内存映射文件中读取数据。
您需要读取二进制字符串的长度和二进制字符串本身。您应该能够将内存映射文件中的切片直接传递给gmpy2.from_binary()
。
我可能更容易为内存映射文件中的每个字节字符串的位置创建(start, end)
值列表,然后将该列表传递给每个进程。
更新:以下是一些使用Python 3.4在Linux上测试过的示例代码。
import mmap
import struct
import multiprocessing as mp
import gmpy2
# Number of mpz integers to place in the memory buffer.
z_count = 40000
# Maximum number of bits in each integer.
z_bits = 750000
# Total number of bytes used to store each integer.
# Size is rounded up to a multiple of 4.
z_size = 4 + (((z_bits + 31) // 32) * 4)
def f(instance):
global mm
s = 0
for i in range(z_count):
mm.seek(i * z_size)
t = struct.unpack('i', mm.read(4))[0]
z = gmpy2.from_binary(mm.read(t))
s += z
print(instance, z % 123456789)
def main():
global mm
mm = mmap.mmap(-1, z_count * z_size)
rs = gmpy2.random_state(42)
for i in range(z_count):
z = gmpy2.mpz_urandomb(rs, z_bits)
b = gmpy2.to_binary(z)
mm.seek(i * z_size)
mm.write(struct.pack('i', len(b)))
mm.write(b)
ctx = mp.get_context('fork')
pool = ctx.Pool(4)
pool.map_async(f, range(4))
pool.close()
pool.join()
if __name__ == '__main__':
main()