Why might my C# computation time be non-deterministic?
I am running a search algorithm which is fed at the start with a single seed. From this point on I expect the algorithm to behave in a deterministic fashion, which it largely does. I can largely verify this by looking at the 10,000th step, 20,000 step and seeing they are identical. What I am seeing different though is the length of thread processor time used to get to the same place (having taken identical paths). I am measuring the thread time with ProcessThread.TotalProcessorTime.
To quantify this I have done some tests for you. I varied the run time and measured the number of solutions evaluated within this time
30s 60s 120s 120s
473,962 948,800 1,890,668 1,961,532
477,287 954,335 1,888,955 1,936,974
473,441 953,049 1,895,727 1,960,875
475,606 953,576 1,905,271 1,941,511
473,283 951,390 1,946,729 1,949,231
474,846 954,307 1,840,893 1,939,160
475,052 952,949 1,848,938 1,934,243
476,797 957,179 1,945,426 1,951,542
475,034 476,599 473,831 486,721
1,478 2,426 23,922 11,108
I repeated the test 8 times for each. The bottom two rows show the Average solutions evaluated over a 30 second period followed by the Standard Deviation. I repeated the 120s test as the standard deviation was so high the first time and much lower the second time.
If my algorithm is doing the same work then what could cause the same work to take different amounts of time? What random开发者_JS百科 element is being introduced?
To clarify a few points:
- I am talking about Thread Processor time and not Clock time
- The algorithm runs on a single thread with no explicit interactions with other threads
- This environment is Windows XP .Net C# Dual processor
- It is a console application
- The algorithm uses the processor and memory, only after it has finished will it print the result to screen.
Best Regards
Optimization, memory management (GC, allocation, paging, etc.) and Just in Time compilation.
On the processor level, cache misses and incorrect branch predicitions can both affect how much processor time might be taken from one run to another. On the framework level, JITing and GC can both affect it as well. The latter are more likely to be observed than the former.
Your algorithm might be deterministic, but absolutely none of the environment and runtime elements are:
- The code runs on a runtime that needs to allocate memory, non-deterministic from your point of view.
- The runtime has a garbage collector that runs at undetermined times for non-deterministic periods, from your point of view.
- The operating system is not soft or hard real time, so the processor management affects the timing.
All in all, don't expect deterministic behaviour in a non-deterministic system. Windows CE supports hard real time, but you'd still need to use something other than .NET on it.
Bear in mind that "deterministic" is in a sense saying: "this piece of code takes exactly 20 milliseconds every single time it runs. You have no hope of achieving this with a runtime that is non-deterministic on an OS that is non-deterministic.
Determinism in the sense of an operating system is usually less stringent than "exactly", more like: "I can guarantee that I reply within X, otherwise I will error". Soft and hard real-time are more and less flexible on this point, respectively.
What resources is your algorithm uses? Are there any other process that use the same resources? This includes CPU, memory, IO (pagefile). Other processes will have an impact on the performance of your algorithm.
What is a difference in time? 1%? 10%?
Processor time is shared time, so any other activity happening on your machine can affect performance.
I stand corrected.
精彩评论