Calculate CPU Charge ?

Discuss the development of new homebrew software, tools and libraries.

Moderators: cheriff, TyRaNiD

Post Reply
Alree
Posts: 33
Joined: Tue Feb 26, 2008 10:50 pm

Calculate CPU Charge ?

Post by Alree »

Hi,

I just want to know if anyone has already make a function in C or in ASM to show the PSP's Cpu charge, like the little plugin HUD ?
or any lib, include in sdk ?
jimparis
Posts: 1145
Joined: Fri Jun 10, 2005 4:21 am
Location: Boston

Post by jimparis »

Are you talking about CPU speed or battery charge?
Either way, check the pspsdk documentation, there are simple functions to get both.
Art
Posts: 642
Joined: Wed Nov 09, 2005 8:01 am

Post by Art »

CPU speed still on the second page where I asked about it:
http://forums.ps2dev.org/viewtopic.php?t=9815
If not actually, then potentially.
Cpasjuste
Posts: 214
Joined: Sun May 29, 2005 8:28 am

Post by Cpasjuste »

I do not think he want to know the cpu speed, but the cpu usage.
Alree
Posts: 33
Joined: Tue Feb 26, 2008 10:50 pm

Post by Alree »

yes it's a mistake I want to know if anyone has already make a function to get "cpu load"

not frequency, but % of cpu load.
I know we need to enumerate all thread to calculate this value, but I don"t want to waste time if a lib or function already exist.
TyRaNiD
Posts: 907
Joined: Sun Jan 18, 2004 12:23 am

Post by TyRaNiD »

It is certainly doable but totally meaningless on a general basis which is what I assume you want it for, some leet VSH plugin crap... It might have some sort of benefit for actual dev I guess. And it doesn't require thread enumeration at all though you can probably do it with that :)
Alree
Posts: 33
Joined: Tue Feb 26, 2008 10:50 pm

Post by Alree »

it's for a benchmark, not a VSH plugin.
TyRaNiD
Posts: 907
Joined: Sun Jan 18, 2004 12:23 am

Post by TyRaNiD »

Okay then :P This would have to be done from kernel mode, you could do it in user mode but you would have to enable the global profiler before it would work. But even with the thread approach you would have to do it kernel mode anyway.

Code: Select all

#define PROFILER_REG_BASE 0xBC400000
void print_cpuusage(void)
{
    PspDebugProfilerRegs *regs = (PspDebugProfilerRegs*) PROFILER_REG_BASE;
    unsigned int *p = (unsigned int*) regs;
    int i;

    for&#40;i = 0; i < &#40;sizeof&#40;PspDebugProfilerRegs&#41; / sizeof&#40;unsigned int&#41;&#41;; i++&#41;
    &#123;
        p&#91;i&#93; = 0;
    &#125;

    regs->enable = 1;

    while&#40;1&#41;
    &#123;
        unsigned int tempck;
        unsigned int tempsl;

        sceKernelDelayThread&#40;1000000&#41;;
        tempck = regs->cpuck;
        tempsl = regs->sleep;
        regs->cpuck = 0;
        regs->sleep = 0;

        printf&#40;"CPU Usage&#58; %d%%\n", &#40;int&#41; &#40;100.0f * &#40;&#40;float&#41; tempck - &#40;float&#41; tempsl&#41; / &#40;float&#41; tempck&#41;&#41;;
    &#125;
&#125;
So that will print the CPU usage every second, the sampling time needs to be short enough to ensure the counters don't wrap. All that calculation is doing is measuring how many active cycles occur vs the number of cycles where the CPU is halted (i.e. in the idle thread). Which is kinda what you want I would expect. However you probably should take that value more as a relative measure than a cast iron percentage.

edit:
Hmm seems I have screwed something up, looks like you need the global profilers enabled correctly as well for some reason. Which sucks :)
Alree
Posts: 33
Joined: Tue Feb 26, 2008 10:50 pm

Post by Alree »

thanks TyRaNiD, I'll try to couple this with another method to reduce error margin.

what do you mean by "enabled correctly" there is a wrong way to enable it ?
TyRaNiD
Posts: 907
Joined: Sun Jan 18, 2004 12:23 am

Post by TyRaNiD »

Urm you have to enable the global profiler switch to get it to look nice, in psplink you can do 'profmode g' in your own code you are on your own ;)
Stewie87
Posts: 34
Joined: Thu Apr 03, 2008 8:16 am

Post by Stewie87 »

TyRaNiD wrote:Okay then :P This would have to be done from kernel mode, you could do it in user mode but you would have to enable the global profiler before it would work. But even with the thread approach you would have to do it kernel mode anyway.

Code: Select all

#define PROFILER_REG_BASE 0xBC400000
void print_cpuusage&#40;void&#41;
&#123;
    PspDebugProfilerRegs *regs = &#40;PspDebugProfilerRegs*&#41; PROFILER_REG_BASE;
    unsigned int *p = &#40;unsigned int*&#41; regs;
    int i;

    for&#40;i = 0; i < &#40;sizeof&#40;PspDebugProfilerRegs&#41; / sizeof&#40;unsigned int&#41;&#41;; i++&#41;
    &#123;
        p&#91;i&#93; = 0;
    &#125;

    regs->enable = 1;

    while&#40;1&#41;
    &#123;
        unsigned int tempck;
        unsigned int tempsl;

        sceKernelDelayThread&#40;1000000&#41;;
        tempck = regs->cpuck;
        tempsl = regs->sleep;
        regs->cpuck = 0;
        regs->sleep = 0;

        printf&#40;"CPU Usage&#58; %d%%\n", &#40;int&#41; &#40;100.0f * &#40;&#40;float&#41; tempck - &#40;float&#41; tempsl&#41; / &#40;float&#41; tempck&#41;&#41;;
    &#125;
&#125;
So that will print the CPU usage every second, the sampling time needs to be short enough to ensure the counters don't wrap. All that calculation is doing is measuring how many active cycles occur vs the number of cycles where the CPU is halted (i.e. in the idle thread). Which is kinda what you want I would expect. However you probably should take that value more as a relative measure than a cast iron percentage.

edit:
Hmm seems I have screwed something up, looks like you need the global profilers enabled correctly as well for some reason. Which sucks :)
I tried it but it gives me always 100%... why?

P.s.: I'm on CF 3.90M33 and I used that function in a VSH plugin...
hlide
Posts: 739
Joined: Sun Sep 10, 2006 2:31 am

Post by hlide »

well even if your plugin is running by interval with an active sleep, it may be still 100% because other threads are still running so there may be no perceptible idle. It suffices there is one plugin of lowest priority with an active events polling or an active idle thread (which means you need to remove its own CPU usage) to make CPU usage 100%.

Or simply there is a misusage of this profiler.
User avatar
Torch
Posts: 825
Joined: Wed May 28, 2008 2:50 am

Post by Torch »

Badly coded plugins can lead to 100% usage (not to mention lowered battery life). Thats why I normally recode simple plugins I find useful for my personal use so that I know its coded right and not wasting battery.

PSPFiler has a CPU usage monitor.
pspjoke
Posts: 14
Joined: Mon Jun 23, 2008 10:10 am

Post by pspjoke »

i have a use for this function in a prx, but of course it always returns 100% in a prx. so can somebody help me to get this working?

oh and its not a "badly coded plugin" in case any one is wondering.
User avatar
Torch
Posts: 825
Joined: Wed May 28, 2008 2:50 am

Post by Torch »

pspjoke wrote:i have a use for this function in a prx, but of course it always returns 100% in a prx. so can somebody help me to get this working?

oh and its not a "badly coded plugin" in case any one is wondering.
I was referring to any other plugins you might have installed and are running.
pspjoke
Posts: 14
Joined: Mon Jun 23, 2008 10:10 am

Post by pspjoke »

oh, well i know there not running the cpu to 100%, its the same with all others off. so does anyone got any advice on how to get this working for a prx?
pspjoke
Posts: 14
Joined: Mon Jun 23, 2008 10:10 am

Post by pspjoke »

so nobody can help me with this?
J.F.
Posts: 2906
Joined: Sun Feb 22, 2004 11:41 am

Post by J.F. »

The thread has all the info you need. We aren't here to write your program for you. You don't even bother to post code while still asking for help... that doesn't fly around here. It pretty much guarantees no one will help. That and bumping the thread after four hours.
pspjoke
Posts: 14
Joined: Mon Jun 23, 2008 10:10 am

Post by pspjoke »

J.F. wrote:The thread has all the info you need. We aren't here to write your program for you. You don't even bother to post code while still asking for help... that doesn't fly around here. It pretty much guarantees no one will help. That and bumping the thread after four hours.
well the code is at the top for one..

however i did change it very slightly so it would function like i need it to.(however still returning 100% making it.. useless) here is the code.

Code: Select all

#define PROFILER_REG_BASE 0xBC400000
int print_cpuusage&#40;void&#41;
&#123;
    PspDebugProfilerRegs *regs = &#40;PspDebugProfilerRegs*&#41; PROFILER_REG_BASE;
    unsigned int *p = &#40;unsigned int*&#41; regs;
    int i;

        for&#40;i = 0; i < &#40;sizeof&#40;PspDebugProfilerRegs&#41; / sizeof&#40;unsigned int&#41;&#41;; i++&#41;
        &#123;
        p&#91;i&#93; = 0;&#125;

    regs->enable = 1;


            

        unsigned int tempck;
        unsigned int tempsl;
        sceKernelDelayThread&#40;1000000&#41;;
        tempck = regs->cpuck;
        tempsl = regs->sleep;
        regs->cpuck = 0;
        regs->sleep = 0;
 
return&#40;&#40;int&#41; &#40;100.0f * &#40;&#40;float&#41; tempck - &#40;float&#41; tempsl&#41; / &#40;float&#41; tempck&#41;&#41;;
&#125;

2 you wouldn't be writing the program for me, just helping me to get one function of the program working.

as far as bumping the thread, well.. yea my bad.
J.F.
Posts: 2906
Joined: Sun Feb 22, 2004 11:41 am

Post by J.F. »

Well, I did my own test based partly on the code at the top, and partly on pspdebug.c. I made a kernel mode prx for the profiler and then used it from a 3.xx user mode app.

Here's main.c for the prx:

Code: Select all

#include <pspsdk.h>
#include <pspkernel.h>
#include <pspdebug.h>


#define VERS 1
#define REVS 0


PSP_MODULE_INFO&#40;"Profiler", 0x1006, VERS, REVS&#41;;
PSP_MAIN_THREAD_ATTR&#40;0&#41;;


#define PROFILER_REG_BASE 0xBC400000
#define PROFILER_REG_COUNT 20


void InitProfiler&#40;void&#41;
&#123;
  	u32 k1;
  	volatile PspDebugProfilerRegs *regs = &#40;volatile PspDebugProfilerRegs *&#41;PROFILER_REG_BASE;

	  k1 = pspSdkSetK1&#40;0&#41;;

    regs->enable = 1;

  	pspSdkSetK1&#40;k1&#41;;
&#125;


void ExitProfiler&#40;void&#41;
&#123;
  	u32 k1;
  	volatile PspDebugProfilerRegs *regs = &#40;volatile PspDebugProfilerRegs *&#41;PROFILER_REG_BASE;

  	k1 = pspSdkSetK1&#40;0&#41;;

    regs->enable = 0;
  	asm&#40;"sync\r\n"&#41;;

  	pspSdkSetK1&#40;k1&#41;;
&#125;


void ClrProfileRegs&#40;void&#41;
&#123;
  	u32 k1, i;
  	volatile u32 *regs = &#40;volatile u32 *&#41;PROFILER_REG_BASE;

  	k1 = pspSdkSetK1&#40;0&#41;;

  	/* Don't clear the enable register */
	  for&#40;i = 1; i < PROFILER_REG_COUNT; i++&#41;
		    regs&#91;i&#93; = 0;

  	pspSdkSetK1&#40;k1&#41;;
&#125;


void GetProfileRegs&#40;PspDebugProfilerRegs *dest&#41;
&#123;
  	u32 k1, i;
  	volatile u32 *regs = &#40;volatile u32 *&#41;PROFILER_REG_BASE;
    u32 *u_regs = &#40;u32 *&#41;dest;

  	k1 = pspSdkSetK1&#40;0&#41;;

	  for&#40;i = 0; i < PROFILER_REG_COUNT; i++&#41;
		    u_regs&#91;i&#93; = regs&#91;i&#93;;

  	pspSdkSetK1&#40;k1&#41;;
&#125;


int module_start&#40;SceSize args, void *argp&#41;
&#123;
	return 0;
&#125;

int module_stop&#40;&#41;
&#123;
	return 0;
&#125;
and here's main.c for the app:

Code: Select all

#include <pspsdk.h>
#include <pspkernel.h>
#include <pspctrl.h>
#include <pspdebug.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>


#define printf pspDebugScreenPrintf


#define VERS    1
#define REVS    0


PSP_MODULE_INFO&#40;"ProfilerTest", 0, VERS, REVS&#41;;
PSP_MAIN_THREAD_ATTR&#40;PSP_THREAD_ATTR_USER&#41;;


void InitProfiler&#40;void&#41;;
void ExitProfiler&#40;void&#41;;
void ClrProfileRegs&#40;void&#41;;
void GetProfileRegs&#40;PspDebugProfilerRegs *dest&#41;;


int main&#40;void&#41;
&#123;
    int i;
    PspDebugProfilerRegs regs;

    pspDebugScreenInit&#40;&#41;;
    pspDebugScreenSetBackColor&#40;0x00000000&#41;;
    pspDebugScreenSetTextColor&#40;0x00ffffff&#41;;
    pspDebugScreenClear&#40;&#41;;
    sceCtrlSetSamplingCycle&#40;0&#41;;
    sceCtrlSetSamplingMode&#40;PSP_CTRL_MODE_DIGITAL&#41;;

  	printf&#40;"\n Profiler Test\n\n"&#41;;

    SceUID mod = pspSdkLoadStartModule&#40;"profiler.prx", PSP_MEMORY_PARTITION_KERNEL&#41;;
    if &#40;mod < 0&#41;
    &#123;
        printf&#40;" Error 0x%08X loading/starting profiler.prx.\n", mod&#41;;
        sceKernelDelayThread&#40;3*1000*1000&#41;;
        sceKernelExitGame&#40;&#41;;
    &#125;

    InitProfiler&#40;&#41;;
    for &#40;i=0; i<10; i++&#41;
    &#123;
        ClrProfileRegs&#40;&#41;;
        sceKernelDelayThread&#40;100*1000&#41;;
        GetProfileRegs&#40;&regs&#41;;
        printf&#40;" CPU usage&#58; %d\n", 100 * &#40;regs.cpuck - regs.sleep&#41; / regs.cpuck&#41;;
    &#125;

    ExitProfiler&#40;&#41;;

    sceKernelDelayThread&#40;3*1000*1000&#41;;
    sceKernelExitGame&#40;&#41;;

    return 0;   /* never reaches here, again, just to suppress warning */
&#125;
It consistently gives me 79% CPU usage with the occasional 80%. Guess sceKernelDelayThread() doesn't do much waiting if there are no other threads.

By the way - remember that these regs are only 32 bits wide. Don't make the measuring period too big or they might overflow, and then who knows what you'd get for a result.
pspjoke
Posts: 14
Joined: Mon Jun 23, 2008 10:10 am

Post by pspjoke »

thank you for your help, and again sorry that my first post on these forums was sucky..
but just so i can be that much more annoying. (jk, not trying to be annoying :( )

when i try to compile the eboot/app. i get this error in my compiler.

Code: Select all

$ make
psp-gcc -I. -I/usr/local/pspdev/psp/sdk/include -Os -G0 -Wall -g -D_PSP_FW_VERSI
ON=150  -L. -L/usr/local/pspdev/psp/sdk/lib   main.o  -lpspdebug -lpspdisplay -l
pspge -lpspctrl -lpspsdk -lc -lpspnet -lpspnet_inet -lpspnet_apctl -lpspnet_reso
lver -lpsputility -lpspuser -lpspkernel -o test.elf
main.o&#58; In function `main'&#58;
/home/Christian/projects/1cpuloadeboot/main.c&#58;49&#58; undefined reference to `InitPr
ofiler'
/home/Christian/projects/1cpuloadeboot/main.c&#58;52&#58; undefined reference to `ClrPro
fileRegs'
/home/Christian/projects/1cpuloadeboot/main.c&#58;54&#58; undefined reference to `GetPro
fileRegs'
/home/Christian/projects/1cpuloadeboot/main.c&#58;58&#58; undefined reference to `ExitPr
ofiler'
collect2&#58; ld returned 1 exit status
make&#58; *** &#91;test.elf&#93; Error 1
so im guessing i need to add a something to my LIBS, however if thats right.. idk what.

for the prx its weird, starting clean it fails with this

Code: Select all

$ make
psp-gcc -I/usr/local/pspdev/psp/sdk/include/libc -I. -I/usr/local/pspdev/psp/sdk
/include -Os -G0 -Wall -g -D_PSP_FW_VERSION=150   -c -o main.o main.c
psp-gcc -I/usr/local/pspdev/psp/sdk/include/libc -I. -I/usr/local/pspdev/psp/sdk
/include -Os -G0 -Wall -g -D_PSP_FW_VERSION=150  -L. -L/usr/local/pspdev/psp/sdk
/lib -Wl,-q,-T/usr/local/pspdev/psp/sdk/lib/linkfile.prx -mno-crt0 -nostartfiles
   main.o  -lpspdebug -lpspdisplay -lpspge -lpspctrl -lpspsdk -lpsplibc -lpsputi
lity -lpspuser -lpspkernel -o cpumanager.elf
psp-fixup-imports cpumanager.elf
Error, no .lib.stub section found
make&#58; *** &#91;cpumanager.elf&#93; Error 1
but if i do "make" again, without changing anything.

Code: Select all

$ make
psp-prxgen cpumanager.elf cpumanager.prx
it compiles... thats just odd.

so how can i fix this to get it to compile?
thanks again for the help.
J.F.
Posts: 2906
Joined: Sun Feb 22, 2004 11:41 am

Post by J.F. »

My post above didn't include all the needed files... it was example code to look at. If you wish to actually try it yourself, you'll need more than just the two mains.

Here's all the code and files... the last compile of the main app was done with 10 sec delay just to see what would happen. You can change that and recompile if you want a shorter test time.

http://www.mediafire.com/download.php?80fn1cnqzem
pspjoke
Posts: 14
Joined: Mon Jun 23, 2008 10:10 am

Post by pspjoke »

ok, and thanks.ill give it a shot if i can get this working ill put you in the credits of my app lol :P
J.F.
Posts: 2906
Joined: Sun Feb 22, 2004 11:41 am

Post by J.F. »

I don't need credit... the code is just a mix of already existing code. :)

As long as it's helpful to somebody, that's enough.
Post Reply