The following code takes 6 seconds to run on a DOS box emulator. Calculate the number of clock cycles required for the highlighted code (A) to run?
Ok so for this part you need to count the number of cycles this program will execute. Each comment will tell you how many
cycles each instruction takes. E.g. It takes 4 clock cycles to run mov bx, 100
. On the jump instructions, you will see
something like '16 backward 4 forward', this means if the jump instruction jumps back, it will yake 16 cycles, if it doesn't
jump, it will take 4.
In this example, when cx > 0, jnz back1
will take 16 cycles. But when cx
== 0, it will take 4 cycles.
+----------------------------- `mov cx, 50000` takes 4 cycles
|
| +---------------------- When cx != 0, `jnz back1` takes 16 cycles + 2 from `dec cx`
| |
| | +------------ This happens 49,999 times, on the 50,000th time, cx == 0 so,
| | |
| | | +- when cx == 0, `jnz back1` only takes 4 cycles + 2 from `dec cx`
| | | |
B = 4 + ((2 + 16) * 49999) + (4 + 2) = 899992
+----------------------------- `mov cx, 50000` takes 4 cycles
|
| +---------------------- When cx != 0, `jnz back2` takes 16 cycles + 2 from `dec cx`
| |
| | +------------ This happens 49,999 times, on the 50,000th time, cx == 0 so,
| | |
| | | +- when cx == 0, `jnz back2` only takes 4 cycles + 2 from `dec cx`
| | | |
C = 4 + ((2 + 16) * 49999) + (4 + 2) = 899992
A =
4 ; `mov bx, 100` Only happens once
99 * (B + C + 2 + 16) ; When `bx != 0`
+ B + C + 2 + 4 ; When `bx == 0`
----------------------
A = 180,000,192 cycles
speed = 180000192 cycles / 6 seconds = 30000032 Hz
= 30.000032 MHz
The above answer seems way too high, but theres a reason for that. Modern processors are able to do three operations
at once. So this means we can estimate the speed of the processor by dividing this number by 3 giving us about 10 MHz
Why would it not be possible to replace code B and C with a single loop with an initial value of CX=100,000?
Although this would result in the same output, the number of cycles would be reduced since the jump forward at
jnz back1
, second mov cx
and second dec cx
would never happen.
mov ah,02
mov dl,'S'
int 021h
mov bx, 100 ; 4 cycles
back3: mov cx, 50000 ; 4
back1: dec cx
jnz back1 ; 16 backward 4 forward
mov cx, 50000 ; 4
back2: dec cx ; 2
jnz back2 ; 16 backward 4 forward
dec bx ; 2
jnz back3 ; 16 backward 4 forward
mov ah,02
mov dl,'F'
int 021h
cycles = 0
bx = 100; cycles = cycles + 4; # mov bx, 100
while True:
# B
B = 0
cx = 50000; cycles = cycles + 4; B = B + 4 # mov cx, 50000
while True:
cx = cx - 1; cycles = cycles + 2; B = B + 2
if cx != 0: # jnz back1
cycles = cycles + 16
B = B + 16
else:
cycles = cycles + 4
B = B + 4
break
# C
C = 0
cx = 50000; cycles = cycles + 4; C = C + 4 # mov cx, 50000
while True:
cx = cx - 1; cycles = cycles + 2; C = C + 2
if cx != 0: # jnz back1
cycles = cycles + 16
C = C + 16
else:
cycles = cycles + 4
C = C + 4
break
bx = bx - 1; cycles = cycles + 2 # dec bx
if bx != 0: # jnz back3
cycles = cycles + 16
else:
cycles = cycles + 4
break
print "B =", B # 899992
print "C =", C # 899992
print "cycles =", cycles # 180000192
speed = cycles / 6
print "Speed =", speed, "Hz"
print "Speed =", speed/1000000.00, "MHz"
print "Speed =", (speed/1000000.00) / 3, "MHz, with parallel processing"
# Speed = 30000032 Hz
# Speed = 30.000032 MHz
# Speed = 10.0000106667 MHz, with parallel processing