8

I have a multi-threaded application, and in a certain section of code I use a Stopwatch to measure the time of an operation:

MatchCollection matches = regex.Matches(text); //lazy evaluation
Int32 matchCount;
//inside this bracket program should not context switch
{
    //start timer
    MyStopwatch matchDuration = MyStopwatch.StartNew();
    //actually evaluate regex
    matchCount = matches.Count;
    //adds the time regex took to a list
    durations.AddDuration(matchDuration.Stop());
}

Now, the problem is if the program switches control to another thread somewhere else while the stopwatch is started, then the timed duration will be wrong. The other thread could have done any amount of work before the context switches back to this section.

Note that I am not asking about locking, these are all local variables so there is no need for that. I just want the timed section to execute continuously.

edit: another solution could be to subtract the context-switched time to get the actual time done doing work in the timed section. Don't know if that's possible.

David S.
  • 5,965
  • 2
  • 40
  • 77

2 Answers2

5

You can't do that. Otherwise it would be very easy for any application to get complete control over the CPU timeslices assigned to it.

You can, however, give your process a high priority to reduce the probability of a context-switch.


Here is another thought:
Assuming that you don't measure the execution time of a regular expression just once but multiple times, you should not see the average execution time as an absolute value but as a relative value compared to the average execution times of other regular expressions.
With this thinking you can compare the average execution times of different regular expressions without knowing the times lost to context switches. The time lost to context switches would be about the same in every average, assuming the environment is relatively stable with regards to CPU utilization.

Daniel Hilgarth
  • 171,043
  • 40
  • 335
  • 443
  • Thanks. See edit. Is it possible to measure and subtract the context-switched time to get the actual time done doing work in the timed section? – David S. Jun 04 '13 at 12:00
  • @DavidS.: I don't know of any way to achieve this. But please see update for another thought. – Daniel Hilgarth Jun 04 '13 at 12:26
  • your update is an excellent suggestion! I like it very much. The vast majority of regexes are fast, so with some sanity checks, the relative value to average times is even more useful than if I had managed to solve the original problem. – David S. Jun 04 '13 at 12:33
2

I don't think you can do that.

A "best effort", for me, would be to put your method in a separate thread, and use

Thread.CurrentThread.Priority = ThreadPriority.Highest; 

to avoid as much as possible context switching.

If I may ask, why do you need such a precise measurement, and why can't you extract the function, and benchmark it in its own program if that's the point ?

Edit : Depending on the use case it may be useful to use

Process.GetCurrentProcess().ProcessorAffinity = new IntPtr(2); // Or whatever core you want to stick to

to avoid switch between cores.

C4stor
  • 8,355
  • 6
  • 29
  • 47
  • In regards to your question, that would require very major architectural changes. I don't need a one-time bechmark, because the text and regex are different every time. It may be possible. I would prefer another solution. I need the precise measurement to detect so that I can optimize or remove regexes, because slow regexes will delay program and add up in such a way that it would end up having very measurable business costs. I'll definitely try the threadpriority. – David S. Jun 04 '13 at 12:12
  • Then you could maybe use a profiler, which let you see how much time you spend in each function :) A free one (with not so much features however) is SlimTune – C4stor Jun 04 '13 at 12:23
  • Thanks, I use profilers but I can't use it as an always-on measurement tool for this issue. – David S. Jun 04 '13 at 12:51