wokwi / avr8js

Arduino (8-bit AVR) simulator, written in JavaScript and runs in the browser / Node.js
https://blog.wokwi.com/avr8js-simulate-arduino-in-javascript/
MIT License
463 stars 73 forks source link

Implement execution throttling when over 100% #20

Closed gfeun closed 3 years ago

gfeun commented 4 years ago

A great issue to write :smile:

So now that the simulation runs faster than the simulated CPU, it would be nice to have the possibility to throttle at 100% speed

Similar to how application target a specific number of Frame Per Second, we could target CPU Freq instructions per second, not more.

This would be implemented in the execute runner function.

Not a priority but nice to have.

urish commented 4 years ago

Indeed!

Actually, I have some prototype for this already, this is what the code looks like:

async execute(callback: (cpu: CPU) => void) {
  this.stopped = false;
  let workUnitCycles = 500000;
  let nextTick = this.cpu.cycles + workUnitCycles;
  for (;;) {
    avrInstruction(this.cpu);
    this.timer.tick();
    this.usart.tick();
    if (this.cpu.cycles >= nextTick) {
      const speed = this.performance.update();
      callback(this.cpu);
      if (speed < 0.95) {
        workUnitCycles = Math.min(500000, Math.floor(workUnitCycles * 1.05));
      } else if (speed < 0.98) {
        workUnitCycles = Math.min(500000, Math.floor(workUnitCycles * 1.01));
      } else if (speed > 1.1) {
        workUnitCycles = Math.max(10000, Math.floor(workUnitCycles / 1.05));
      } else if (speed > 1.02) {
        workUnitCycles = Math.max(10000, Math.floor(workUnitCycles / 1.01));
      }
      await new Promise(resolve => setTimeout(resolve, 0));
      if (this.stopped) {
        break;
      }
      nextTick += workUnitCycles;
    }
  }
}
gfeun commented 4 years ago

Ah right, that make sense. I like the gradual threshold approach.

arcostasi commented 3 years ago

This week I studied a little about execution throttling when over 100% My friend Uri gave me the path of the stones, at the beginning I got a lot complicated, but then I simplified it and I thought the operation improved, but then I decided to complicate it a little more and here is another way. https://github.com/arcostasi/avr8js-electron-playground/commit/a45fc06a9813046ceddc0b3e517f92e25d4a5a4f

urish commented 3 years ago

Thanks for sharing it @arcostasi