gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

DS development > 2 questions re visualizing performance

#132232 - sourcerer - Sun Jun 24, 2007 10:07 pm

Hi,
I have two questions on which I'd love to see some suggestions.

1) In order to visualize general performance it's nice to have something to show how far on the frame you are (like changing color 0 or drawing a line). Does anyone have an idea about a general solution to do something like that? I guess the line driven rendering of DS should make something like this possible - maybe set a position of something in the HBL after your processing is done?
2) Is there an easy way to access a hi-res timer to profile code?...without ARM7?

(sure miss printf functionality to then show that timer without having to have another screen dedicated to showing the info).

Any input appreciated,
Kaj

#132257 - tepples - Mon Jun 25, 2007 3:18 am

On the GBA, I used to change BG_PALETTE[0] at various points in the frame.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#132279 - Chano Marrano - Mon Jun 25, 2007 1:01 pm

You can enable an interrupt at horizontal blank that increases some counter. If the counter at vertical blank is 92 and the DS has 192 horizontal lines, the CPU usage would be 92/192 = 0.479 => 48%.

This approach works well on GBA, but I'm not sure if it works on DS using the two screens.

#132305 - tepples - Mon Jun 25, 2007 7:46 pm

On the DS, pixels are fed to both screens simultaneously. However, there are 192 display lines and 71 vertical blanking lines for a total of 263 lines.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#132310 - Sunray - Mon Jun 25, 2007 8:26 pm

Setup a timer to measure a certain scope or what ever. You now that the frame time is 16 ms (60 fps).


Edit: I post my timer code

Code:


class ScopeTimer
{
public:
   ScopeTimer(const char *pName);
   ~ScopeTimer();

private:
   const char *m_pName;
};



static volatile int g_TimerCounter = 0;
static void TimerInterrupt()
{
   g_TimerCounter++;
}

ScopeTimer::ScopeTimer(const char *pName) : m_pName(pName)
{
#ifdef DEBUG
   if (TIMER3_CR & TIMER_ENABLE)
   {
      log("ScopeTimer: TIMER3 already enabled!\n");
      TIMER3_CR &= ~TIMER_ENABLE;
   }
#endif
   g_TimerCounter = 0;

   irqSet(IRQ_TIMER3, TimerInterrupt);
   irqEnable(IRQ_TIMER3);

   TIMER3_DATA = TIMER_FREQ(100000);
   TIMER3_CR = TIMER_ENABLE | TIMER_IRQ_REQ | TIMER_DIV_1;
}

ScopeTimer::~ScopeTimer()
{
   TIMER3_CR = 0;
   irqDisable(IRQ_TIMER3);

   log("%s: %.02f ms\n", m_pName, g_TimerCounter * 0.01f);
}



void SomeFunc()
{
   ScopeTimer t("SomeFunc");
   DoStuff();
}

#132320 - HyperHacker - Mon Jun 25, 2007 10:16 pm

Chano Marrano wrote:
You can enable an interrupt at horizontal blank that increases some counter. If the counter at vertical blank is 92 and the DS has 192 horizontal lines, the CPU usage would be 92/192 = 0.479 => 48%.

This approach works well on GBA, but I'm not sure if it works on DS using the two screens.
Interesting, I've been looking for a way to measure CPU usage as a percent. Am I understanding this correctly?
1) Once you're finished whatever you're doing for this frame, enable the hblank interrupt, which increments a counter each time it fires.
2) In vblank, divide the counter by 263 and multiply by 100 for your percent, then disable the hblank interrupt and reset the counter.

Is that correct?

BTW, someone added a debug function to Super Mario World once that I think did basically the same thing. A star appears at the left of the screen, and the further down it is, the higher the CPU usage. I'm guessing he just set the star's Y position to the current scanline before entering the wait-for-vblank loop.
_________________
I'm a PSP hacker now, but I still <3 DS.

#132325 - Chano Marrano - Mon Jun 25, 2007 10:33 pm

Okay, some pseudo code:

Code:
u32 counter;

void HBLinterruptFunc()
{
    counter++;
}

void updateScreen()
{
    ...
    printf("CPU: %d%", (counter * 100) / HORIZONTAL_LINES);
    waitForVBL();
    counter = 0;
    ...
}


I hope you understand it better. The color change approach only works if the CPU usage is lower than 100%. I have used the counter approach on my GBA engine and it works without problem, and it lets you measure an unlimited CPU usage per frame:
http://eltiosinchorra.sitesled.com/demoGBA.zip

Quote:
Once you're finished whatever you're doing for this frame, enable the hblank interrupt, which increments a counter each time it fires.

Nope, the hblank interrupt is always enabled.

#132379 - sourcerer - Tue Jun 26, 2007 10:52 am

That's kinda like what I was looking at now, but I don't quite understand the code.

Your code seems to assume the timers count in microsecond precision (the 100000 and 0,1f seem to hint at that) or something like that, but I thought they run in system clock frequency or divisions thereof?

K