Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!rice!uupsi!psivax!torkil From: torkil@Pacesetter.COM (Torkil Hammer) Newsgroups: comp.sys.ibm.pc.misc Subject: Timing the CPU and bus size Keywords: 386 386sx, 8088 and 8086 etc Message-ID: <1990Sep20.231706.27009@Pacesetter.COM> Date: 20 Sep 90 23:17:06 GMT Organization: Pacesetter Systems Inc., Sylmar, CA Lines: 49 Everything can be timed, including CPU speed, memory speed and prefetch queue. The trick is to do incremental measurements. Suppose you have written the routine that measures the system timer's low bits (in Turbo C it is outportb(0x43,0x00); low byte = inportb(0x40); high byte = inportb(0x40); - but you have to write it in assembler to really know what you get). Each bit increment corresponds to about 1 microsecond (actually 1/1.19318) but don't be surprised if you never see any odd bit count. It counts down, by the way. Now you put 2 of these back to back. The difference in readings is the time it took to read the clock, roughly proportional to the CPU speed. On a 16 MHz machine, that time should be about 16 clicks or 13 usec, depending on the actual assembler code. Of course, you should first wait until the clock() just incremented, then do the 2 readings so you don't get interrupted in the middle. Actually, do several measurements and screen out bad ones. In between you now sandwich something like [mov cx,100; rep nop] and the difference from before is what these instructions took. Now replace 100 with 200, and the incremental difference is the exact time it takes to do 100 prefetched nops on location, a number that only depends on the CPU speed (such as 5 CPU clock cycles per rep nop). Replace 100 with 10100 for greater accuracy. Also, replace rep nop (5 cycles) with rep mov bx,cx (4 cycles) for an independent check. Rotates of varying count is another way to get an incremental time that depends only on CPU speed. (1 incremental CPU clock per incremental rotate per repeat, but that only works on 80188 and up, though you can write a loop that switches cx between loop count and rotate count for the 8088) Once you have the exact CPU speed, you get the memory wait cycles from switching between a register operation (mov bx,ax) and a memory operation (mov [si],bx) inside the rep and measure the incremental time. You have to look up the cycles required for each operation. You should get the prefetch queue size from doing a backwards loop and expanding the scope of it with nop's. Once you fall over the edge, the time should go up by more than the cpu cycles in the nop's. (I haven't tried) After this you can play with 8, 16 and 32 bit instructions to tell the bus time and then the size of the bus. Enjoy Torkil Hammer