18% speedup from interrupt optimization

This commit is contained in:
2023-09-20 10:44:24 +02:00
parent 7556dca4f6
commit f911a78d84
3 changed files with 54 additions and 28 deletions

View File

@@ -19,7 +19,7 @@ fun main(args: Array<String>) {
cpu.runState = CPU.RunState.RUNNING
cpu.pc = 0x80u
val start = System.nanoTime()
val ninsn = cpu.run()
val ninsn = cpu.run(50000000)
val end = System.nanoTime()
System.err.println("Halted at 0${cpu.pc.toString(8)}")
@@ -29,4 +29,5 @@ fun main(args: Array<String>) {
println("Exiting")
console.stop()
}
System.exit(0)
}

View File

@@ -828,6 +828,7 @@ class CPU(val mbus: MemBus) {
try {
if (runState == RunState.HALTED) return
if (mbus.unibus.interruptPending) {
for (i in 7 downTo (psw_priority + 1)) {
if (pirq bit 8 + i) {
logger.debug("PIRQ{} trap to 0xA0", i)
@@ -845,6 +846,12 @@ class CPU(val mbus: MemBus) {
break
}
}
} else {
val pirqLvl = pirq.toInt() shr 1 and 7;
if (pirqLvl > psw_priority) {
trap(0xA0u)
}
}
if (runState == RunState.WAIT_FOR_INTERRUPT) {
return
}
@@ -867,6 +874,15 @@ class CPU(val mbus: MemBus) {
fun run(): Long {
var ninsn: Long = 0
while (runState == RunState.RUNNING) {
ninsn += run(Long.MAX_VALUE)
step()
}
return ninsn
}
fun run(nstep: Long): Long {
var ninsn: Long = 0
while (runState == RunState.RUNNING && ninsn < nstep) {
ninsn++
step()
}

View File

@@ -77,6 +77,9 @@ class Unibus: PAddressSpace, Subregion(12, 6) {
private val logger = LoggerFactory.getLogger(this.javaClass)
private val queue: Array<MutableList<InterruptSource>> = Array(8) { Vector(4) }
private var interruptCount: Int = 0
val interruptPending: Boolean
get() = interruptCount > 0
override fun map(address: UInt): PAddressSpace =
super.map(address) ?: throw BusTimeoutError(address)
@@ -101,11 +104,17 @@ class Unibus: PAddressSpace, Subregion(12, 6) {
/// to fetch the currently desired interrupt vector
fun assertInterrupt(priority: Int, device: InterruptSource) {
val list = queue[priority]
if (list.isEmpty()) {
interruptCount++
}
if (!list.contains(device)) list.add(device)
}
fun deassertInterrupt(priority: Int, device: InterruptSource) {
queue[priority].remove(device)
val lvlQueue = queue[priority]
if (lvlQueue.remove(device) && lvlQueue.isEmpty()) {
interruptCount--
}
}
// Checks for an interrupt. The handler receives (priority, device)