在进程之间共享gmpy2多精度整数而不复制

时间:2016-05-08 15:15:59

标签: python multiprocessing gmpy

是否可以在进程(由多处理创建)之间共享gmpy2 multiprecision整数(https://pypi.python.org/pypi/gmpy2)而无需在内存中创建副本? 每个整数大约有750,000位。整数不会被进程修改。

谢谢。

1 个答案:

答案 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()