Seeing significant (almost exponential) drops in clock performance with small increases in the amount of instructions

Hello,
I am programming a Rabbit RCM6700 and have noticed some concerning issues regarding the overall performance. According to the manuals, the Rabbit 6000 processor utilized by the RCM 6700 has a maximum clock speed of 162 MHz.

So to test this I wrote a simple program which simply toggles the state of an IO pin in a loop. If I toggle only one pin, and measure the frequency with either an oscilloscope or a logic analyzer I observe a frequency of ~1.20 MHz, however if I toggle an additional pin, the frequency drops all the way to a whopping 720 kHz!

I’ve also observed other irregularities by examining the IO pin in the logic analyzer large gaps in between activity (sometimes as large as .4 seconds before activity begins again). Whats more is the square waves is not perfectly square with occasionally smaller than normal pulses. I have observed these same issues in other programs of mine that are running on RCM 6700 and have tried swapping boards as well.

I’ve also checked the status of the GCSR and GCDR registers and nothing seems out of order. My basic questions are:

  1. Why is the RCM 6700 not running at 1.62 MHz?
  2. Why are cycles taking such a massive hit with minor operation increases?
  3. What is causing the large gaps of inactivity? I am not employing an CPU rest functions

See code below:
https://pastebin.com/2knb68xK

You can have Dynamic C generate a .LST file showing the generated assembly for those statements, and the Instruction Set Reference from the Help menu will show you how many clock cycles each assembly op code requires.

With the BitWrPortI() function, you’re loading a byte from memory (the shadow register), updating a bit in it, saving the byte, and writing it out to an I/O register.

If you’re running within the Dynamic C debugger, the gaps in activity could be due to communication between the debug kernel and Dynamic C. You also have a periodic interrupt updating MS_TIMER and SEC_TIMER and hitting a watchdog for you.

You could move your test code to a function labeled “__nodebug” and see how that improves performance.

I’m not sure of the electrical issues, other than to look at PA1CR to control drive strength, output slew and whether the pin is configured with a pullup/down resistor.

I assume you’re just doing some benchmarks at this point, but if you actually need fast digital I/O you should consider using bare assembly, or configuring an I/O pin for PWM output.