Thanks for talking about me, I feel special...
I did a quick test, actually I started to write a long reply then figured I would just do it first then come back.
The first test:
mov r0,#0x2800
mov r2,#0x90000
add r3,r2,#24
0x70000:
str r1,[r2]
str r1,[r2]
...
str r1,[r2]
subs r0,r0,#1
moveq pc,lr
mov pc,#0x70000
There is a total of 10000 str instructions, so 0x2800 or 10240 times through the loop and 10000 writes per loop is 102,400,000 total str instructions.
Test two:
mov r0,#0x2800
mov r2,#0x90000
add r3,r2,#24
0x70000:
str r1,[r2]
str r1,[r3]
...
str r1,[r2]
str r1,[r3]
subs r0,r0,#1
moveq pc,lr
mov pc,#0x70000
Same number of writes but they alternate between two addresses 24 apart (I am writing words and the alignment fault bit is set by the bootloader, so I need a nice number, ideally I would have used a prime number here).
I called this code from C and read the timer (in C) before and after. both tests took the same amount of time. It was 9 something seconds, but read on...
I used the ART103 bootloader, made a non-OS (no linux) program that runs on the 920. The cache and wb are not enabled. So for every store to memory, there is a read from memory to fetch the next instruction.
So if you simply divide the execution time by 102,400,000 you are wrong by a factor of at least two.
Second, if you have a small loop like:
mov r0,#0x2800
mov r2,#0x90000
add r3,r2,#24
0x70000:
str r1,[r2]
str r1,[r3]
subs r0,r0,#1
bne 0x70000
The subs fetch, execute, the bne fetch, execute and pipe flush will actually overshadow the writes to memory (and their instruction fetches). So this loop should run I guess half the speed...Let me try right now:
Nope, I am wrong, it looks to be 10 times longer. Will have to think about that a bit.
Anyway, that is why I did a long loop with 10,000 strs, so that the affect of the subs and bne are somewhat insignificant. I didnt actually type str r1,[r2] 10,000 times, I took the disassembly and basically wrote the instructions to memory from the program before running the test:
writeto(0x70000-12,0xe3a00b0a);
writeto(0x70000- 8,0xe3a02809);
writeto(0x70000- 4,0xe2823018);
for(ra=0;ra<10000;ra+=4)
{
writeto(0x70000+ra,0xe5821000);
ra+=4;
writeto(0x70000+ra,0xe5831000);
}
writeto(0x70000+ra,0xe2500001); ra+=4;
writeto(0x70000+ra,0x01a0f00e); ra+=4;
writeto(0x70000+ra,0xe3a0f807); ra+=4;
start=dtime();
jumpto(0x70000-12,0xABCD1234);
stop=dtime();
printf("%lu\n",stop-start);
Thus the easily relocatable end of the loop:
subs r0,r0,#1
moveq pc,lr
mov pc,#0x70000
Instead of a subs, bne
Anyway, my guess from this test puts us at 94ns for a read and write cycle combined or 47ns per cycle assuming they take the same amount of time or around 20 million memory cycles per second, putting memory at 10 times slower than the cpu.
I dont know how far you want to take this. For me the right answer is have cache on for the area you want to run the test loop and cache off for the area you want to test the writes to. The test memory (where you write to) needs the write buffer on.
use a short/small loop like the one above. Again, that loop is in cached memory so it should ultimately run from cache and not affect system memory until the loop is finished. The writes go to the write buffer which will smooth out the writes and allow the subs and bne and such to execute without affecting the timing of the test. Lets put it this way, the write buffer is full (in this case because of addresses not data) the subs comes from cache, one cycle to read it and the execution is one cycle (these are not additive, while one thing is executing another is fetching in the same cycle). So one cycle for the subs, another for the bne, give it maybe two for the pipe to flush and get to the first str in the loop the next time around. So 4 or 5 clocks, a single write from the write buffer has not completed, so that first str in the loop holds the cpu in wait states until the write buffer can finish one of the writes, as soon as that happens one store executes, then next store hangs the cpu waiting another 10 clocks or so for the write buffer then it executes filling the write buffer again, the subs and bne are shadowed by a write by the write buffer and we start over. If the write buffer is not enabled then the subs and bne are going to be counted in the timing.
My guess is that for the random you perhaps calculated the random number in the loop instead of pre-calculating? I would need to see the three loops to get a better guess on what happened in your test.
This kind of thing is not a case of looking to see what asm was generated but write the code in asm.
I assume you were running linux on the 920? The 920 interrupts should be disabled completely (simply write to the register to disable all of them). And the 920 should be placed in a very tight infinite loop, literally a while(1); no polling the keyboard or anything, an infinite loop that will keep it in the cache and off the system memory/ i/o bus. If not the 920 will jump on the bus and affect your timing.
I assume you are doing byte writes (an address difference of 321 has to be byte writes). What are you ultimately planning to do, copy memory? Words go four times faster, Above I had 20million CYCLES per second but 80million BYTES per second because they were word cycles.
its really late here, I am tired, I may do this experiment tomorrow. I am very interested in this topic. I am still hung up on a couple of sentances in the marketing datasheet for this chip. The two cpus, and the peripherals do share a bus, but the bus is supposedly designed so that four things can jump on at once without affecting each other. I dont know what that means. In theory the 920 can read from a register, while the 940 does something, maybe some bank of memory while the video is reading memory to write to the display. Getting a good write/read test like this THEN changing it so the 920 is say polling a register instead of just a while(1); loop. we know the video is already stomping on the bus, perhaps reading up on the video and halting it, that sort of thing...