Reputation: 290
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
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