lich
lich

Reputation: 290

Python+SimPy hold for process computation time

I want to make simulation where the service time depends on computation complexity of some function.

The request arrival should not stop due to the function processing. For testing I use example function that utilizes cpu for some seconds:

sorted([float(random.random()) for i in range(1000000)])

How can I call it to simulate service, but do not prevent new service request arrival. If I call this function, new service request arrives just after function execution, not at the stated time.

def visit(self, timeAtNAT, res):
  arrive=time.clock()-startTime
  print("%7.4f. Packet #%s arrived." % (time.clock()-startTime, self.name))
  yield request, self, res
  wait = time.clock()-startTime - arrive
  print("%7.4f. Packet #%s waited %6.3f" % (time.clock()-startTime, self.name, wait))
  sorted([float(random.random()) for i in range(1000000)])  
  yield release, self, res
  print("%7.4f. Packet #%s left" % (time.clock()-startTime, self.name))

So, in my example new Packet arrives only after previous packet was left.

I tried to use multiprocessing, but I got naming collision (of Process class). I am novice in SimPy, parallel programming and Python.

Upvotes: 0

Views: 864

Answers (1)

incidentnormal
incidentnormal

Reputation: 115

I think you're mixing methodologies here, if you're simulating complex calculations - you don't actually do the complex calculation - you make an algorithm that calculates the order of magnitude of time that the calculation would take, and then add some random jitter to it (i.e. change it by +/- 5% or something).

SimPy is a Discrete Event Simulation framework - meaning that all computations effectively occur instantaneously in simulation time, because the simulation won't move on to the next event (and to move forward in simulation time, moving on to the next event must occur- {although moving onto the next event does not imply moving forward in simulation time, as the next event may be occurring at the same time}).

Let's make this algorithm that calculates the time that the complex calculation takes. Let's make it an algorithm of exponential complexity, i.e. in big O notation: O(2n)

def calculateComputationComplexity(self, cValue):
    #lets make this an exponential algorithm
    algorithmTime = 0
    if cValue < 17:
        algorithmTime = 2**cValue
    else:
        algorithmTime = 2**16
    return algorithmTime

Then in your code add a yield hold command:

def visit(self, timeAtNAT, res):
    arrive=time.clock()-startTime
    print("%7.4f. Packet #%s arrived." % (time.clock()-startTime, self.name))
    yield request, self, res
    wait = time.clock()-startTime - arrive
    print("%7.4f. Packet #%s waited %6.3f" % (time.clock()-startTime, self.name, wait))

    waitTime = self.calculateComputationComplexity(10)
    yield hold, self, waitTime

    yield release, self, res
    print("%7.4f. Packet #%s left" % (time.clock()-startTime, self.name))

Where 10 should be replaced with an int that represents the complexity of the calculation. DES frameworks do not use multithreading, they simply calculate everything deterministically, in order, and then add it to the timeline of events to occur.

Upvotes: 0

Related Questions