GP2X Any Update On 2nd Cpu?


As for the memory clock rate, I'm pretty sure it runs at 1/2 of the CPU clock. If you had it running at 7MHz, performance would be abysmal.
 
Squidge posted on Jul 12 2006 at 06:00 PM said:
Seems like someone needs to read my power consumption posts....

Yes, please, where. Did you use actual batteries or an external supply and something to measure current?

There is far too many web pages for me to absorb, starting on this platform so late in the game. And I am too eager to just run code, that I dont want to spend weeks or months reading. So I am going to re-invent the wheel a few times here.

No matter where I turn you have already been there, just point me at all of your (public) code so I will have less to absorb or re-invent...



BradN posted on Jul 12 2006 at 06:11 PM said:
As for the memory clock rate, I'm pretty sure it runs at 1/2 of the CPU clock. If you had it running at 7MHz, performance would be abysmal.

I would say 3mips vs 135mips is abysmal.

Thanks though, again trying to absorb too much too fast...
 
Last edited by a moderator:
People who are too eager and want to just run code normally fall flat on there face, so may I suggest you actually step back a bit, learn and understand the platform first, before trying to code? While it may be exciting to jump in and start coding, you'll only be hiting your head against a brick wall on a regular basis unless you understand what you are doing.

I really don't have a repository for all my knowledge and source code - you have to search the gp2x forums for that (and maybe some of the gp32 forums for when I posted in the wrong sections :D )

In the gp2x general forum, there is a still a newish post from me about current consumption, and also one from a good few months ago. One was powered via the DC In jack, and the other via the battery connectors - both methods using a variable voltage (0-30v with 0.1V increments) power supply.
 
I am reading and studying, I assure you. I just read up on the MPU and programmed it the way I wanted it (and did some runs to see how much each part contributes).

Anyway, I disabled interrupts both on the 940 http://www.dwelch.com/gp2x/gcc940-20060713b.zip
And on the 920
http://www.dwelch.com/gp2x/simple2-20060711d.zip
Yet, the test still takes a different amount of time each run. The timer is a fraction of the speed of the cpu, so to get runs that are say 20 ticks or more from each other. 20 timer ticks is in the 550 sys clocks range. What do you suppose would cause that? Video refreshes competing with the ram? I would still think, so long as the video and cpu are synchronized (an assumption) you would still get the same results with the exception of where in the refresh cycle you start the test, vary that and the first conflict affects the first cache miss which causes different delays than other cache misses. that is my complicated guess, perhaps there is something simpler, in theory it has to be hardware as there shouldnt be anything interfering with software...

Do you know if the 920 is the master of the interrupts? How are they shared between cores? Basically if I disable interrupts on one side, well I guess it would affect both there is only one intterupt mastk register, not two. Anyway, if I wanted to enable interrupts, would linuxes handler get in the way of anything I might want to do on the 940? Or does the 940 only get certain interrupts like the ones from the inter cpu communication registers?

David
 
If I remember, I think hardware interrupts are only routed to the 920 - I'm not sure if this is configurable or not.
 
dwelch posted on Jul 13 2006 at 10:34 PM said:
Do you know if the 920 is the master of the interrupts? How are they shared between cores? Basically if I disable interrupts on one side, well I guess it would affect both there is only one intterupt mastk register, not two. Anyway, if I wanted to enable interrupts, would linuxes handler get in the way of anything I might want to do on the 940? Or does the 940 only get certain interrupts like the ones from the inter cpu communication registers?

David

I can't speek for the 920 and linux but i've used the intrupts on the 940 with no problems. The main trap I fell into is the docs a wrong. The 940 HW interupt control registers are in a different place, someone found them from looking at the FW source. My 940 code is coded as if it were the only cpu in the system so it looks like they are seperate. The regs are at 0xc0004500.
 
Last edited by a moderator:
BradN posted on Jul 14 2006 at 08:35 AM said:
If I remember, I think hardware interrupts are only routed to the 920 - I'm not sure if this is configurable or not.

That was indeed the case until we found the 940 interrupt control registers :) (They are 'documented' in the 2.0 uboot). Basically identical to the 920 interrupt registers, but at a different address.

So, at offset 4500, you'll find the following registers for the 940:

volatile U32 SRCPEND;
volatile U32 INTMODE;
volatile U32 INTMASK;
volatile U32 PRIORIT;
volatile U32 INTPEND;
volatile U32 INTOFST;
 
Last edited by a moderator:
Squidge posted on Jul 14 2006 at 07:58 AM said:
That was indeed the case until we found the 940 interrupt control registers :) (They are 'documented' in the 2.0 uboot). Basically identical to the 920 interrupt registers, but at a different address.

Ahhh, and thats exactly why I want to watch what registers the firmware manipulates when it boots up...
 
Last edited by a moderator:
dwelch posted on Jul 14 2006 at 03:47 PM said:
Squidge posted on Jul 14 2006 at 07:58 AM said:
That was indeed the case until we found the 940 interrupt control registers :) (They are 'documented' in the 2.0 uboot). Basically identical to the 920 interrupt registers, but at a different address.

Ahhh, and thats exactly why I want to watch what registers the firmware manipulates when it boots up...

The easiest way to do that is probably by looking at the released source code - most likely easier than writing down the registers read/written and the values, and then trying to figure out what it's doing.
 
Last edited by a moderator:
Hmmm.... if interrupts can be used on the 940 now, does that mean various emulators could be updated to use raster interrupts controlled by the 940? I'm thinking something like having the emulator update a list of palette switches/etc in the upper 32MB, and the 940 updates them as the screen draws.
 
BradN posted on Jul 14 2006 at 07:15 PM said:
Hmmm.... if interrupts can be used on the 940 now, does that mean various emulators could be updated to use raster interrupts controlled by the 940? I'm thinking something like having the emulator update a list of palette switches/etc in the upper 32MB, and the 940 updates them as the screen draws.

Yes, that's possible.

It's also possible to take over the interrupts on the 920 and do it there, too.
 
Last edited by a moderator:
I will leave Dzz's thread alone for a while and live in mine.

I am going to harp on this again, a quote from the MP2520f data sheet:

"MP2520F can handle four parallel data access operations through allowing four out of nine bus master to access one of the four internal data buses independently and concurrently."

I think they mean four of the

"one DRAM memory bus, one Non-DRAM memory & Fast I/O bus, one I/O Peripheral bus and one local data bus".


This means two processors can be faster than one if you arrange them right. Have to figure out how to do that.

Moving data from the 920 to the 940 is a delicate procedure. You should not (IMO) have the shared memory cached from the 920 side. It doesnt buy you any performance, in fact it slows you down as you have to flush the cache. the write buffer will help if you are doing a memcpy from cache to non-cached wb enabled ram. or if you are inventing the data. preferrably writing in words or quad words instead of bytes to take full advantage of the write buffer.

On the 940 you want to move the data out of the way, unless you are double buffering, so that the 920 can work on the next block of data while the 940 is working on the current block. This means memcpy again (for a single buffer).

So I had this fear that memcpy wasnt optimized, gotta test, gotta know.

The first one I happened to find was this one

.global _gmemcopy
_gmemcopy:
mov ip,#0
b gmemtest
gmemtop:
ldrb r3,[ip,r1]
strb r3,[ip,r0]
add ip,ip,#1
subs r2,r2,#1
gmemtest:
bcs gmemtop
bx lr

(Renamed it so I could test it independent of whatever memcpy the compiler used).

Which is exactly the kind of thing I was afraid of. Then I wrote these to compare speeds

.global wcopy
wcopy:
cmp r2,#0
b wtest
wtop:
ldr r3,[r1],#4
str r3,[r0],#4
subs r2,r2,#4
wtest:
bhi wtop
bx lr

.global xcopy2
xcopy2:
stmdb r13!,{r4}
cmp r2,#0
b xtest2
xtop2:
ldmia r1!,{r3-r4}
stmia r0!,{r3-r4}
subs r2,r2,#8
xtest2:
bhi xtop2
ldmia r13!,{r4}
bx lr

.global xcopy4
xcopy4:
stmdb r13!,{r4-r6}
cmp r2,#0
b xtest4
xtop4:
ldmia r1!,{r3-r6}
stmia r0!,{r3-r6}
subs r2,r2,#16
xtest4:
bhi xtop4
ldmia r13!,{r4-r6}
bx lr

Basically copy 4 bytes at a time, 8 or 16.

And as expected my xcopys were around 4 times faster. Assuming we really do have a 32 bit data bus (which this confirms) one read or write cycle can move 4 bytes (32 bits). an strb or ldrb only gives 8 bits per cycle with 24 bits unused, a big waste. Had it been 2 times faster that would have indicated a 16 bit data bus.

Before posting this I looked for some C source for memcpy as the above looks very much like compiled C instead of asm. I had just started using a new to me compiler, winarm. gcc 4.1.1, built for embedded and runs on windows, supposedly with newlib. but none of the memcpys in gcc or newlib looked like this (there were more than one in each place). In fact the new lib ones were huge, trying to decide direction to copy and what size chunks to use. So I changed back to my compiler with newlib, sure enough newlib's memcy was only slightly slower than the word, double word and quad word above. Granted memcpy has the overhead of actually copying every byte which the test functions above dont.

Then I downloaded glibc and uClibc to see their memcpy's. Turns out between gcc, newlib, glibc and uClibc there were several memcpy's. uClibc was the only one with any assembler.

bottom line there is no rule on what memcpy you are going to get. at a minimum fill up the bus on every cycle. ldm/stm pairs will take advantage of the write buffer if you are in a situation to take advantage of it. Any read from memory drains the write buffer first, so if you are executing out of non-cached memory the write buffer drains and you gained nothing. If your source is not cached, then the write buffer drains and you gain nothing. I did not try an exhaustive test on various copy lengths, I did, interestingly see 2048 do much better than 8192 bytes for one of the off the shelf memcpys (maybe the one in devkitGP2X).

Hmm, did I mention above the devkitGP2X's memcpy, was between 1.5 and 2.0 times slower than the 1, 2, and 4 word copies above?
 
Back
Top