在不复制的情况下在进程之间共享 gmpy2 多精度整数

sharing gmpy2 multi-precision integer between processes without copying

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

谢谢。

更新:测试代码如下。

我会尝试以下未经测试的方法:

使用 Python 的 mmap 库创建内存映射文件。

使用gmpy2.to_binary()gmpy2.mpz实例转换为二进制字符串。

将二进制字符串的长度和二进制字符串本身写入内存映射文件。为了允许随机访问,您应该以固定值的倍数开始每次写入,在您的情况下为 94000。

用您的所有值填充内存映射文件。

然后在每个进程中,使用gmpy2.from_binary()从内存映射文件中读取数据。

您需要读取二进制字符串的长度和二进制字符串本身。您应该能够将内存映射文件中的切片直接传递给 gmpy2.from_binary().

我可能更简单地为内存映射文件中每个字节字符串的位置创建一个 (start, end) 值列表,然后将该列表传递给每个进程。

更新:这是一些示例代码,已在 Linux 和 Python 3.4.

上进行了测试
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()