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

@@ -18,15 +18,16 @@ fun main(args: Array<String>) {
cpu.loadAbs(File(args[0]))
cpu.runState = CPU.RunState.RUNNING
cpu.pc = 0x80u
val start = System.nanoTime()
val ninsn = cpu.run()
val end = System.nanoTime()
val start = System.nanoTime()
val ninsn = cpu.run(50000000)
val end = System.nanoTime()
System.err.println("Halted at 0${cpu.pc.toString(8)}")
val time = (end-start).toDouble() / 1_000_000_000.0
println("Executed ${ninsn} in ${time}s: ${ninsn/time} i/s")
val time = (end - start).toDouble() / 1_000_000_000.0
println("Executed ${ninsn} in ${time}s: ${ninsn / time} i/s")
} finally {
println("Exiting")
console.stop()
}
System.exit(0)
}

View File

@@ -111,11 +111,11 @@ class CPU(val mbus: MemBus) {
val bitset = pirq shr 8
var maxp: UShort = 0u
for (i in 7 downTo 1) {
if (bitset bit i) {
maxp = i.toUShort() shl 1
break
}
}
if (bitset bit i) {
maxp = i.toUShort() shl 1
break
}
}
field = value and 0xFE00u or maxp or (maxp shl 4)
}
@@ -828,21 +828,28 @@ class CPU(val mbus: MemBus) {
try {
if (runState == RunState.HALTED) return
for (i in 7 downTo (psw_priority + 1)) {
if (pirq bit 8+i) {
logger.debug("PIRQ{} trap to 0xA0", i)
trap(0xA0u)
break
if (mbus.unibus.interruptPending) {
for (i in 7 downTo (psw_priority + 1)) {
if (pirq bit 8 + i) {
logger.debug("PIRQ{} trap to 0xA0", i)
trap(0xA0u)
break
}
val source = mbus.unibus.checkInterrupt(i)
if (source != null) {
// we might have been waiting for an interrupt
runState = RunState.RUNNING
val vector = source.vector
logger.debug("Unibus interrupt at pri {} to {}", i, vector)
trap(vector)
source.handled()
break
}
}
val source = mbus.unibus.checkInterrupt(i)
if (source != null) {
// we might have been waiting for an interrupt
runState = RunState.RUNNING
val vector = source.vector
logger.debug("Unibus interrupt at pri {} to {}", i, vector)
trap(vector)
source.handled()
break
} else {
val pirqLvl = pirq.toInt() shr 1 and 7;
if (pirqLvl > psw_priority) {
trap(0xA0u)
}
}
if (runState == RunState.WAIT_FOR_INTERRUPT) {
@@ -865,12 +872,21 @@ class CPU(val mbus: MemBus) {
}
fun run(): Long {
var ninsn: Long = 0
var ninsn: Long = 0
while (runState == RunState.RUNNING) {
ninsn++
ninsn += run(Long.MAX_VALUE)
step()
}
return ninsn
return ninsn
}
fun run(nstep: Long): Long {
var ninsn: Long = 0
while (runState == RunState.RUNNING && ninsn < nstep) {
ninsn++
step()
}
return ninsn
}
fun trap(vector: UShort) {

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)