1

For a bit of context, I am writing a simple CPU emulator. The emulator process boils down to calling a 'step' function to read and execute the next operation in the program. Currently this is just done as fast as possible in a while loop.

I would like the code to be cross-platform but (unfortunately) windows is the primary target.

I need to be able to execute my Emulator->step() function at regular intervals in the range of 1,000Hz to 100,000Hz.

  • For a slower loop I would simply use sleep() but (on windows at least) it doesn't have the resolution for such a high frequency.

  • I have also toyed with spinning a loop checking a Boost microsecond timer. Ignoring the inaccuracy of this method, it uses up real CPU time whilst it is meant to be 'idle'. I am running several emulated CPUs concurrently in threads so the while loop causes a noticeable impact on performance.

Surely there is a method of doing what I want to do with C++?

Mudf4ce
  • 166
  • 1
  • 7

3 Answers3

0

You can't sleep precisly under Windows (maybe the Windows Performance counter functions help, see Is there a Windows equivalent of nanosleep?).

You said that you run many simulated CPU's concurrently in threads, so one possible solution is to throw the threads away and do the Schedueling for the different CPU's yourself (round robin).

Community
  • 1
  • 1
Quonux
  • 2,975
  • 1
  • 24
  • 32
0

You don't need any special sleep resolution. At the end of each loop, just compute whether you need to sleep or not. If not, run the next loop. If so, sleep for the calculated amount. It won't matter if you sleep a little extra on one loop because this logic will make you sleep less on the next loop.

David Schwartz
  • 179,497
  • 17
  • 214
  • 278
  • Logically yes, but sleep on windows has a minimum resolution of 1ms and each 'step' only takes 3-10ns which means that you would need to run a batch of hundreds of steps for each sleep. – Mudf4ce Apr 04 '13 at 10:53
  • 1
    If that's a problem, then *that* is your real problem. Explain it in detail and we'll help you solve it. General purpose operating systems don't let you control the CPU at that level. Instead, they give you other ways of doing all the things you might want that kind of control for. – David Schwartz Apr 04 '13 at 10:54
  • maybe you should do 100...1000 iterations and then sleep for a millisecond, would that solve your problem? – Quonux Apr 04 '13 at 11:19
  • 1
    And please be aware, that the sleep resolution is 1ms but its accuracy is worse (15ms on my machine) – ogni42 Apr 04 '13 at 11:19
  • 3
    @ogni42: It shouldn't matter. If you find you've slept for too long, you just don't sleep on the next however many loops. If it does matter, then the problem is how to make it not matter, which depends on why it does matter, which we don't know. – David Schwartz Apr 04 '13 at 11:20
  • "*but sleep on windows has a minimum resolution of 1ms*" - is that true? I thought that `sleep(0)` gave up the timeslice but didn't delay. Can someone correct me if wrong? – Roger Rowland Apr 04 '13 at 11:25
  • The CPUs will be 'networked' IE have joint access to virtual hardware in the program. Running 1000 steps of one and then 1000 steps of the next could produce some strange behaviour. I can put them into my own scheduler (as Quonux suggested) to keep a certain amount of consistency, step all of the CPUs at once several times and then sleep. I was hoping for a 'better' answer but that should work, its an OS level limitation isn't it? @roger_rowland, you are correct, what I mean by min resolution is that you can't sleep for 0.01ms, only 1ms increments, as ogni42 said realistically 3-20ms min. – Mudf4ce Apr 04 '13 at 13:00
  • @Mudf4ce: Yeah, it's your responsibility to code your program to do the work you want done in the order you want it done. The OS can't do that for you. – David Schwartz Apr 04 '13 at 13:18
0

If you are using a C++11 compiler, have a look at <chrono>. There you can find high precision timers. But be aware, that in a windows environment, these still have low accuracy, which Microsoft will hopefully fix in the next release.

ogni42
  • 1,232
  • 7
  • 11