Xerxes,
The HPGCC3 developers were kind enough to point out that I didn't compile with optimization (doh!). Furthermore, Claudio Lapilli provided two other versions that run even faster.
New results for publication:
Structured C Reg. vars ARM AssemblyPlease also post the 6Mhz (very slow mode) numbers. I think it illustrates that you can get great performance and low battery usage with HPGCC3.6Mhz 0.007060 0.006133 0.005235
75Mhz 0.000560 0.000484 0.000404
192Mhz 0.000213 0.000192 0.000150
Thanks.
Reg Vars Source:
main()
{
register int x, y, r, s, t, n, Ax;
int a[9];for (n = 100000; n > 0; --n) {
r = 8;
s = 0;
x = 0;
Ax = 0;
do {
a[x] = Ax;
++x;
Ax = r;
do {
++s;
y = x;
while (y > 1) {
--y;
if (!(t = Ax - a[y]) || x - y == abs(t)) {
y = 0;
while (!--Ax) {
--x;
Ax = a[x];
}
}
}
} while (y != 1);
} while (x != r);
}
return s;
}
ARM Assembly Source:
#define _ASM asm volatileint benchmark_asm() __attribute__ ((naked));
int benchmark_asm()
{
_ASM("STMDB SP!,{ R1-R8 }");
// 20 R=8
_ASM("MOV R3,#8"); // R3=R
// 30 REM DIM A(R) (DIM used if necessary)
_ASM("SUB SP,SP,R3,LSL #2");
_ASM("SUB SP,SP,#8"); // EXTRA SPACE JUST IN CASE
_ASM("MOV R4,#102400"); // N= APPROX. 100000 ITERATIONS
_ASM("LOOPSTART:");
_ASM("MOV R1,#0"); // R1=X
_ASM("MOV R2,#0"); // R2=Y
_ASM("MOV R0,#0"); // R0=S
_ASM("MOV R6,#0"); // A(X)
_ASM("LINE40:");
//40 IF X=R THEN 180 (140 for all solutions)
_ASM("CMP R1,R3");
_ASM("BEQ LINE180");
//50 X=X+1
_ASM("STR R6,[SP,R1,LSL #2]");
_ASM("ADD R1,R1,#1");
//60 A(X)=R
_ASM("MOV R6,R3");
_ASM("LINE70:");
//70 S=S+1
_ASM("ADD R0,R0,#1");
//80 Y=X
_ASM("MOV R2,R1");
//90 Y=Y-1
_ASM("LINE90:");
_ASM("SUBS R2,R2,#1");
//100 IF Y=0 THEN 40
_ASM("BEQ LINE40");
//110 T=A(X)-A(Y)
_ASM("LDR R7,[SP,R2,LSL #2]");
_ASM("SUBS R7,R6,R7"); // R7=T
//120 IF T=0 THEN 140
_ASM("BEQ LINE140");
//130 IF X-Y<>ABS T THEN 90
_ASM("RSBMI R7,R7,#0"); // ABS(T)
_ASM("SUB R8,R1,R2"); // R8=X-Y
_ASM("CMP R7,R8");
_ASM("BNE LINE90");
_ASM("LINE140:");
//140 A(X)=A(X)-1
_ASM("SUBS R6,R6,#1");
//150 IF A(X)<>0 THEN 70 (<>0 omitted if possible)
_ASM("BNE LINE70");
// 160 X=X-1
_ASM("SUBS R1,R1,#1");
_ASM("LDR R6,[SP,R1,LSL #2]");
//170 IF X<>0 THEN 140 (<>0 omitted if possible)
_ASM("BNE LINE140");
_ASM("LINE180:");
_ASM("SUBS R4,R4,#1");
_ASM("BNE LOOPSTART");
_ASM("ADD SP,SP,#8");
_ASM("ADD SP,SP,R3,LSL #2");
_ASM("LDMIA SP!,{R1-R8}");
_ASM("MOV PC,LR");
}