18% speedup from interrupt optimization
This commit is contained in:
@@ -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)
|
||||
}
|
||||
|
@@ -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) {
|
||||
|
@@ -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)
|
||||
|
Reference in New Issue
Block a user