Measuring the time that a function takes

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

User avatar
DRW
Posts: 2225
Joined: Sat Sep 07, 2013 2:59 pm

Measuring the time that a function takes

Post by DRW »

Is there a way to measure the time that a certain function takes to process? I'm thinking of something that is immediately visible on the screen, so I don't have to stop the game and check some stuff in the binary code of the emulator's PPU or something.

For example, is there a way to read the current pixel position that the cathode ray is in the moment? This way I could read that value, store it into a variable and then use a few debug sprites to display that value on the screen.

Or something else to manipulate the screen output so that I see what the cathode ray is drawing in the moment.
My game "City Trouble":
Gameplay video: https://youtu.be/Eee0yurkIW4
Download (ROM, manual, artworks): http://www.denny-r-walter.de/city.html
User avatar
rainwarrior
Posts: 8734
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: Measuring the time that a function takes

Post by rainwarrior »

Writes to $2001 (PPUMASK) take effect immediately. Turning on greyscale + a colour emphasis can be a great way to mark on the screen when a particular thing happened. This is what I do in my own project.

(Greyscale in conjunction with emphasis is important because it replaces black with grey, so you don't lose the ability to see the mark against black.)
User avatar
rainwarrior
Posts: 8734
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: Measuring the time that a function takes

Post by rainwarrior »

Alternatively, if you're using an emulator, in FCEUX you can create LUA scripts that would measure timing information and overlay it on the screen for you. I often use this when debugging to visualize hitboxes, etc.
User avatar
DRW
Posts: 2225
Joined: Sat Sep 07, 2013 2:59 pm

Re: Measuring the time that a function takes

Post by DRW »

Thanks. Writing to PPUMASK seems to be the best way for me.
Writing a LUA script would mean that I first have to read how this works.
My game "City Trouble":
Gameplay video: https://youtu.be/Eee0yurkIW4
Download (ROM, manual, artworks): http://www.denny-r-walter.de/city.html
lidnariq
Posts: 11432
Joined: Sun Apr 13, 2008 11:12 am

Re: Measuring the time that a function takes

Post by lidnariq »

Thefox's NintendulatorDX variant adds a set of registers at $402X/$403X for timing:
NintendulatorDX readme wrote:Cycle Counting Timers
---------------------
16 CPU cycle counting timers are available for timing different parts of your code. The timers can only be used by writing to a register at the moment. They work by writing to register $402x when you want the timing to start, and to $403x when you want it to end. "x" is the timer number.

E.g.

Code: Select all

  ; Start timer #5. The written value doesn't matter.
  sta $4025
  ; Do whatever.
  nop
  lda #123
  ; Stop timer #5. After this the Debugger window will display the
  ; number of CPU cycles taken by the above code block (4 cycles).
  sta $4035
The number of cycles taken by the STA instructions do not count into the reported number of cycles!

By defining a specially named symbol it's possible to define a name for the timer. The symbol name should be "__timerN_title", and it should point to a zero terminated string containing the name of the timer (replace N with the timer number). This name is displayed in the Debugger window.

E.g.

Code: Select all

  .code
    __timer5_title:
      .asciiz "nmi routine"
The following macros may be useful:

Code: Select all

  .macro startTimer timer
    sta $4020 + timer
  .endmacro

  .macro stopTimer timer
    sta $4030 + timer
  .endmacro

  .macro timerTitle timer, title
    .ident( .sprintf( "__timer%d_title", timer ) ):
      .asciiz title
  .endmacro
Known problems:
* The address of the registers ($402x/$403x) overlaps the FDS register area.

See also:
* [Lua] NDX.getCPUCycles()
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Measuring the time that a function takes

Post by tokumaru »

I would simply set grayscale + emphasis in the beginning of the function, and return to normal in the end. This should give a very clear visual indication of how much of the frame's time is being spent on the function. You could even use different emphasis configurations if you wanted to time different functions.
tepples
Posts: 22708
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Measuring the time that a function takes

Post by tepples »

More methods to measure execution time:
  1. Setup up a mapper's interval timer for some estimate of your subroutine's duration, run the subroutine, and then count cycles until the IRQ triggers.
  2. Do the above using APU DMC. Play a 1-byte sample at maximum rate through the DMC, wait for the IRQ, play the sample at a lower rate, call the subroutine, and then count cycles until a second IRQ triggers.
  3. Make your program buildable for both the NES and Super NES. The latter has a readable H/V counter.
  4. Set up your subroutine's preconditions, then run it in a 6502 simulator that counts cycles.
But for me, the easiest way is to open the debugger of FCEUX for Windows, set a breakpoint at the start of the subroutine, run the program until the subroutine starts, click "Step Out", and then check the cycle counter. It'll be of the form "CPU cycles: xxxxxxxxx (+yyyy)"; the yyyy is how many cycles the subroutine takes. This breaks down, however, if the subroutine runs once a frame and has an execution time varies based the player's actions in the last few frames, because it's so hard to send input to a program where a breakpoint triggers every frame. Is this the problem you're running into?
User avatar
DRW
Posts: 2225
Joined: Sat Sep 07, 2013 2:59 pm

Re: Measuring the time that a function takes

Post by DRW »

Isn't this all a huge overkill? To me, writing to PPUMASK seems to be the most straightforward and easy to implement thing. And it gives me a pretty accurate, easy to see at first glance output

About the FCEUX debugger: That's what I wanted to avoid. Because I want to see how much time everything takes during regular gameplay.
So, yes, actions that take different time every frame might be an issue. In the moment, I don't have a specific problem. I just want to have a general way to measure the time. Especially since I have to split the game logic in three parts since I have the status bar and the parallax split. So, I want to see what I can push into the smaller parts.
My game "City Trouble":
Gameplay video: https://youtu.be/Eee0yurkIW4
Download (ROM, manual, artworks): http://www.denny-r-walter.de/city.html
User avatar
darryl.revok
Posts: 520
Joined: Sat Jul 25, 2015 1:22 pm

Re: Measuring the time that a function takes

Post by darryl.revok »

It sounds to me like the best thing for what you need is to use the cycle counting timers with NintendulatorDX.

This is what I do when I need to gauge the length in cycles of a routine, the entire program, the vBlank handler, or essentially any part of the program that can be marked with a start and stop position.

With this you get an average of what the total has been while your program has been running, which sounds like what you want.
zzo38
Posts: 1096
Joined: Mon Feb 07, 2011 12:46 pm

Re: Measuring the time that a function takes

Post by zzo38 »

Often I just try to count the cycles manually. This won't work if it is too complicated though.
(Free Hero Mesh - FOSS puzzle game engine)
User avatar
Kasumi
Posts: 1293
Joined: Wed Apr 02, 2008 2:09 pm

Re: Measuring the time that a function takes

Post by Kasumi »

DRW codes in C, so counting cycles manually isn't an option.
User avatar
Drew Sebastino
Formerly Espozo
Posts: 3496
Joined: Mon Sep 15, 2014 4:35 pm
Location: Richmond, Virginia

Re: Measuring the time that a function takes

Post by Drew Sebastino »

What's he coding in C for if he's concerned about cycle count? :lol:
User avatar
rainwarrior
Posts: 8734
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: Measuring the time that a function takes

Post by rainwarrior »

Espozo wrote:What's he coding in C for if he's concerned about cycle count? :lol:
Performance always matters when your CPU time is limited, and I guess this surprises you, but it actually even matters more when using C.

Using C is like trying to work with a CPU with 1/10th the power. You probably have a LOT more need to monitor performance to check on your budget than when doing things an assembly. :P

It's also very easy to write code that looks simple in C, but accidentally generates horribly slow code. This is yet another reason why you need to check frequently, because otherwise it's hard to know when you wrote something that destroyed your timing budget.
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Measuring the time that a function takes

Post by tokumaru »

Could Espozo have meant that DRW shouldn't be using C if he's concerned about the cycle count?
lidnariq
Posts: 11432
Joined: Sun Apr 13, 2008 11:12 am

Re: Measuring the time that a function takes

Post by lidnariq »

Of course that's what Espozo meant. Espozo's also made it clear in the past that he doesn't understand the point of using any higher-level language, so it's not clear that his point is useful.
Post Reply