Grey line trick to know how much cpu is used

Discuss technical or other issues relating to programming the Nintendo Entertainment System, Famicom, or compatible systems. See the NESdev wiki for more information.

Moderator: Moderators

Post Reply
User avatar
Banshaku
Posts: 2417
Joined: Tue Jun 24, 2008 8:38 pm
Location: Japan
Contact:

Grey line trick to know how much cpu is used

Post by Banshaku »

I read a long time ago in this thread (or maybe another one, I cannot remember clearly) this trick to show how much CPU is used with a gray line using the monochrome bit.

This was a nice little trick shown by Tepples BUT... I didn't read it well. Instead of using it before the vblank, I was using it during the NMI to know how much the NMI was long.

What I want to know is does it make sense to use it that way? When the music driver was taking more time (famitracker) while switching frame, the line was lower and I know that Jsr documented about this behavior with the driver so it seemed to work.

Does anybody used it that way? If it does work, then it tells me how long is my NMI code. I just want to know if my reading error made me found a way to now more about my NMI or I'm just using unpredictable information generated from that trick used at the wrong place.
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Post by tokumaru »

I guess it works as you described, I just don't think it is as useful as knowing how much free time you have left in the frame.

Knowing how much time your NMI takes may be interesting if you are trying to reduce it through some optimization, but in the end it just counts as part of the general processing of the frame and won't tell you much.

What I like to do is make the screen grayscale (and/or use some color emphasis) as soon as my frame calculations are done and I have nothing to do but wait for the NMI. The gray area (I don't really like to have just a line because it's not as evident) then represents how much free time I have left. It's interesting to observe how it gets smaller as more objects are processed or when there is scrolling. I only restore color back to normal in the NMI, so that the top of the screen is displayed with the correct colors.
User avatar
Banshaku
Posts: 2417
Joined: Tue Jun 24, 2008 8:38 pm
Location: Japan
Contact:

Post by Banshaku »

ok, I see the point. The reason I used the grey line inside the NMI is because of all the talk about your writing buffer code spilling out of it. Because of that, I understood that code segment the wrong way I used it to check if my writes where fine or not.

I will check tomorrow how much my current buffering takes time then with that trick. That's interesting.
doynax
Posts: 162
Joined: Mon Nov 22, 2004 3:24 pm
Location: Sweden
Contact:

Re: Grey line trick to know how much cpu is used

Post by doynax »

Yes, this is a useful technique. We used to call it the poor-man's profiler on the C64 ;)
Note that you can use several different emphasis bit combinations to highlight the CPU-use of the various major subsystems of your game.

Another crude profiling method I've found useful is to continually increase a counter in a loop when you're done with all the processing for a frame, and then read it out and display the final value from the NMI handler.
That way you can more accurately measure savings from optimizations (using replays to get the before and after values) and keep track of maximum/minimum/average frame times over longer spans of time.
User avatar
koitsu
Posts: 4201
Joined: Sun Sep 19, 2004 9:28 pm
Location: A world gone mad

Post by koitsu »

We used to use the exact method you and others describe on the Apple IIGS as well.

The most common method there was to set the screen border colour to a specific colour of your choice (at the start of the routine) and then set it back to whatever it was originally (at the end of the routine). The IIGS border only supported 16 colours, but that was more than enough. These were controlled via simple memory-mapped registers $C022 and $C034.

Since the border on the IIGS wasn't part of the actual on-screen graphics memory area, what you'd end up with is a "section" of the left and right screen borders displaying as the colour you chose.

You could use this in NMI or anywhere else as a cheap form of profiling. It gave you an idea, visually, of how much time a routine took up. I cannot count how many times I used this method when working on demos or anything else that was CPU-intensive -- you could very quickly determine what routine was responsible for what amount of CPU munching. :-) "That drawing routine I wrote is almost 2x slower than the audio routine?! What the hell. Let's try unrolling these loops..."
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Post by tokumaru »

Banshaku wrote:The reason I used the grey line inside the NMI is because of all the talk about your writing buffer code spilling out of it.
Remember that $2006/$2007 operations can't be done during the pre-render scanline either, so make sure to take that scanline into consideration.
tepples
Posts: 22708
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Post by tepples »

tokumaru wrote:Remember that $2006/$2007 operations can't be done during the pre-render scanline either, so make sure to take that scanline into consideration.
Really? I thought they were OK up until the point when the hardware executes what loopy called "v=t". I seem to remember that happening sometime in the pre-render scanline's hblank, close to x=304.
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Post by tokumaru »

Now you got me... I really can't say for sure... But I always read in the docs that the rendering pipeline is initialized during that scanline and that once the NMI fires there are exactly 20 scanlines (not 21) for PPU updates... This sort of thing made me believe that the pre-render scanline was off limits, but I haven't tested myself.
User avatar
Banshaku
Posts: 2417
Joined: Tue Jun 24, 2008 8:38 pm
Location: Japan
Contact:

Post by Banshaku »

So the way it would work is when you don't use the line, you set the monochrome bit after that cpu intensive phase and reset the bit in the NMI. So one part of the screen would become grey, right?

I think that I must be doing it wrong because the screen always stay grey (or I'm quite a heck of a coder but I don't think so :lol: ).

I did it quite fast at 1h in the morning so I must have goofed up somewhere. Basically, the current main loop is something like:

Code: Select all

MainLoop:
  - Process input
  - Process view buffer
  - Set monochrome bit
  - Wait nmi
     + inside NMI, reset monochrome bit
  - read joypad input
jump to mainLoop
So this is how it would be done, right?
tepples
Posts: 22708
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Post by tepples »

The only thing initialized in line -1 is the first two slivers of line 0, fetched from x=320 to x=335.
User avatar
Banshaku
Posts: 2417
Joined: Tue Jun 24, 2008 8:38 pm
Location: Japan
Contact:

Post by Banshaku »

doh, Tepples was faster than me to write a message and I cannot really update mine with the second question ;) So what I understand now is the NMI is 20 scanlines only. So this mean if I use the grey line trick inside the NMI and the line seems a few times near the 20th line because of the sound driver changing frame, this mean I'm already borderline for my update then?
JunoMan
Posts: 15
Joined: Fri Jul 17, 2009 12:00 am

Post by JunoMan »

I set the monochrome bit at the start of my NMI routine and reset it after I've done all the PPU updates. (which are all at the start of the NMI)

The sound driver code can be executed at the end of the NMI as it doesnt matter if the PPU is running.

Thinking about it, I wonder if anyone can tell the difference in the timing of the music as it might be updated at slightly different times in the frame depending on how long the PPU updates take.

edit: Is there any emulator which will inform you when PPU writes are done with the screen is on?
tepples
Posts: 22708
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Post by tepples »

JunoMan wrote:The sound driver code can be executed at the end of the NMI as it doesnt matter if the PPU is running.

Thinking about it, I wonder if anyone can tell the difference in the timing of the music as it might be updated at slightly different times in the frame depending on how long the PPU updates take.
Nobody wll give a care if notes are occasionally 3 to 8 ms late. Humans play notes late anyway, which is why games like DDR usually have at least a 33 ms window to get a "Perfect" judgment. And music engines round key-ons up or down to the nearest 17-20 ms anyway if a song's tempo doesn't divide evenly into 900 (NTSC) or 750 (PAL). If it really matters to you, and you have a sprite 0 scroll split, try running music at a predictable time after the sprite 0 hit.
edit: Is there any emulator which will inform you when PPU writes are done with the screen is on?
I don't have FCEUX in front of me, but I'd be surprised if it doesn't let you put a breakpoint on writes to $2000-$3FFF with condition "vcount < 241".
JunoMan
Posts: 15
Joined: Fri Jul 17, 2009 12:00 am

Post by JunoMan »

tepples wrote: I don't have FCEUX in front of me, but I'd be surprised if it doesn't let you put a breakpoint on writes to $2000-$3FFF with condition "vcount < 241".
The conditions on a breakpoint seem to only able to reference addresses. There's no way of getting the current vertical position. (at least in fceuxdsp-1_07)
Post Reply