Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8573769
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 11, 20262026-06-11T19:19:33+00:00 2026-06-11T19:19:33+00:00

I wrote simple monte-carlo π calculation program in Python, using multiprocessing module. It works

  • 0

I wrote simple monte-carlo π calculation program in Python, using multiprocessing module.
It works just fine, but when I pass 1E+10 iterations for each worker, some problem occur, and the result is wrong. I cant understand what is the problem, because everything is fine on 1E+9 iterations!

import sys
from multiprocessing import Pool
from random import random


def calculate_pi(iters):
    """ Worker function """

    points = 0  # points inside circle

    for i in iters:
        x = random()
        y = random()

        if x ** 2 + y ** 2 <= 1:
            points += 1

    return points


if __name__ == "__main__":

    if len(sys.argv) != 3:
        print "Usage: python pi.py workers_number iterations_per_worker"
        exit()

    procs = int(sys.argv[1])
    iters = float(sys.argv[2])  # 1E+8 is cool

    p = Pool(processes=procs)

    total = iters * procs
    total_in = 0

    for points in p.map(calculate_pi, [xrange(int(iters))] * procs):
        total_in += points

    print "Total: ", total, "In: ", total_in
    print "Pi: ", 4.0 * total_in / total
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-11T19:19:35+00:00Added an answer on June 11, 2026 at 7:19 pm

    The problem seems to be that multiprocessing has a limit to the largest int it can pass to subprocesses inside an xrange. Here’s a quick test:

    import sys
    from multiprocessing import Pool
    def doit(n):
      print n
    if __name__ == "__main__":
      procs = int(sys.argv[1])
      iters = int(float(sys.argv[2]))
      p = Pool(processes=procs)
      for points in p.map(doit, [xrange(int(iters))] * procs):
        pass
    

    Now:

    $ ./multitest.py 2 1E8
    xrange(100000000)
    xrange(100000000)
    $ ./multitest.py 2 1E9
    xrange(1000000000)
    xrange(1000000000)
    $ ./multitest.py 2 1E10
    xrange(1410065408)
    xrange(1410065408)
    

    This is part of a more general problem with multiprocessing: It relies on standard Python pickling, with some minor (and not well documented) extensions to pass values. Whenever things go wrong, the first thing to check is that the values are arriving the way you expected.

    In fact, you can see this problem by playing with pickle, without even touching multiprocessing (which isn’t always the case, because of those minor extensions, but often is):

    >>> pickle.dumps(xrange(int(1E9)))
    'c__builtin__\nxrange\np0\n(I0\nI1000000000\nI1\ntp1\nRp2\n.'
    >>> pickle.dumps(xrange(int(1E10)))
    'c__builtin__\nxrange\np0\n(I0\nI1410065408\nI1\ntp1\nRp2\n.'
    

    Even without learning all the details of the pickle protocol, it should be obvious that the I1000000000 in the first case is 1E9 as an int, while the equivalent chunk of the next case is about 1.41E9, not 1E10, as an int. You can experiment

    One obvious solution to try is to pass int(iters) instead of xrange(int(iters)), and let calculate_pi create the xrange from its argument. (Note: In some cases an obvious transformation like this can hurt performance, maybe badly. But in this case, it’s probably slightly better if anything—a simpler object to pass, and you’re parallelizing the xrange construction—and of course the difference is so tiny it probably won’t matter. Just make sure to think before blindly transforming.)

    And a quick test shows that this now works:

    import sys
    from multiprocessing import Pool
    
    def doit(n):
      print xrange(n)
    
    if __name__ == "__main__":
        procs = int(sys.argv[1])
        iters = int(float(sys.argv[2]))
        p = Pool(processes=procs)
        for points in p.map(doit, [iters] * procs):
          pass
    

    Then:

    $ ./multitest.py 2 1E10
    xrange(10000000000)
    xrange(10000000000)
    

    However, you will still run into a larger limit:

    $ ./multitest.py 2 1E100
    OverflowError: Python int too large to convert to C long
    

    Again, it’s the same basic problem. One way to solve that is to pass the arg all the way down as a string, and do the int(float(a)) inside the subprocesses.

    As a side note: The reason I’m doing iters = int(float(sys.argv[2])) instead of just iters = float(sys.argv[2]) and then using int(iters) later is to avoid accidentally using the float iters value later on (as the OP’s version does, in computing total and therefore total_in / total).

    And keep in mind that if you get to big enough numbers, you run into the limits of the C double type: 1E23 is typically 99999999999999991611392, not 100000000000000000000000.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I was trying to write a simple Monte Carlo simulation program. To be exact,
I wrote simple class in JS witch works, but i had problem when i
I wrote simple class that on the start it just increase the value of
I wrote a simple XML file and a DTD file including an entity, but
I wrote a simple plugin which sets some css code using wp_options. It all
I wrote a simple test program for opencv to see if it's working after
I wrote a simple C program: #include <unistd.h> #include <stdio.h> int main( int argc,
A couple of month ago I wrote a simple program in Java. I have
I have a program which performs a Monte Carlo-type simulation. Currently I have written
I wrote my simple desktop program in C#. I am reluctant to distribute it

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.