PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Benchmark für Raspberry Pi



HaWe
02.12.2014, 19:16
hallo,
mich würde jetzt wirklich mal interessieren, wie schnell der RPI bei benchmark-Tests abschneidet, und zwar
1x unter C
1x unter Python - und, wenn möglich,
1x unter Java.


Einen Benchmark Test für verschiedene MCUs habe ich schon - jetzt müsste man ihn nur für den RPi anpassen.

http://www.mindstormsforum.de/viewtopic.php?f=71&t=8095&start=60#p64772


Setup + design:
This benchmark test is including several test functions for different individual computational patterns:
- simple basic integer arithmetics (addition/substraction, multiplication/division),
- real and transcendental float arithmetic functions (sqrt,sin,cos, exp), preferably 64bit double (=> bonus points)
- advanced matrix algebra for more-dim array manipulation (matrix product + determinant, built-in or imported) (genuine multi-dim arrays => bonus points)
- pseudo random number generator (Mersenne Twister): low-level bit- and-byte-operations like AND, XOR, SHIFT-left/right
- quick high-level sort algorithm for arrays[500] (preferably Shellsort, built-in or imported),
- a text-output and a 2D-graphics test for graph + shape + fill computation and lcd output stressing.

the latest brickbench test enhancement also takes programming-environments into account, i.e.
- available memory, networking/chaining abilities,
- variable types (e.g. for double precision fp and matrices/more-dim arrays),
- recursions,
- multithreading support,
- and, last but not least, the wholeness of API functions for hardware (screen, and attached sensors and motors), and the IDE.


Wenn Python nämlich WIRKLICH geschwindigkeitsmäßig an C herankommt, wäre es ja wirklich eine Alternative.
Wer hat Lust und traut sich?

Der C-Code ist vorhanden und sicher leicht portierbar, mit Python und Java kenne ich mich (noch) nicht aus.
Den Grafik-Teil kann man notfalls (erstmal) weglassen und evtl später nachreichen.

Hier ist der C-Referenz-Code (danach auch einige Adaptationen, u.a. für Java, aber hier ist ein kleiner Fehler drin):

http://www.mindstormsforum.de/viewtopic.php?f=71&t=8095&start=60#p64494



// HaWe brickbench
// benchmark test for NXT/EV3 and similar Micro Controllers
// PL: gpp CSLite C/C++, C-API and BCC by John Hansen
// Autor: (C) Helmut Wunder 2013,2014
// freie Verwendung für private Zwecke
// für kommerzielle Zwecke nur nach Genehmigung durch den Autor.
// protected under the friendly Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
// http://creativecommons.org/licenses/by-nc-sa/3.0/
// version 1.08.2

#include <stdio.h>
#include <math.h>
#include <fcntl.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/ioctl.h>

#include "lms2012.h"
#include "ev3_button.h"
#include "ev3_lcd.h"
#include "ev3_constants.h"
#include "ev3_command.h"
#include "ev3_timer.h"
#include "ev3_lcd.h"
#include "ev3_sound.h"
#include "ev3_output.h"


unsigned long runtime[8];

int a[500], b[500], c[500], t[500];


//--------------------------------------------
// Mersenne Twister
//--------------------------------------------

unsigned long randM(void) {
const int M = 7;
const unsigned long A[2] = { 0, 0x8ebfd028 };

static unsigned long y[25];
static int index = 25+1;

if (index >= 25) {
int k;
if (index > 25) {
unsigned long r = 9, s = 3402;
for (k=0 ; k<25 ; ++k) {
r = 509845221 * r + 3;
s *= s + 1;
y[k] = s + (r >> 10);
}
}
for (k=0 ; k<25-M ; ++k)
y[k] = y[k+M] ^ (y[k] >> 1) ^ A[y[k] & 1];
for (; k<25 ; ++k)
y[k] = y[k+(M-25)] ^ (y[k] >> 1) ^ A[y[k] & 1];
index = 0;
}

unsigned long e = y[index++];
e ^= (e << 7) & 0x2b5b2500;
e ^= (e << 15) & 0xdb8b0000;
e ^= (e >> 16);
return e;
}

//--------------------------------------------
// Matrix Algebra
//--------------------------------------------

// matrix * matrix multiplication (matrix product)

void MatrixMatrixMult(int N, int M, int K, double A[][M], double B[][K], double C[][K]){
int i, j, s; // matrix A: N x M // B: M x K // C: N x K
for (i=0; i<N; ++i) {
for (j=0; j<K; ++j) {
C[i][j]=0;
for (s=0; s<M; ++s) {
C[i][j]=C[i][j] + A[i][s]*B[s][j];
}
}
}
}


// matrix determinant

double MatrixDet(int N, double A[N][N])
{
int i,j,i_count,j_count, count=0;
double Asub[N-1][N-1], det=0;

if(N==1) return A[0][0];
if(N==2) return (A[0][0]*A[1][1] - A[0][1]*A[1][0]);

for(count=0; count<N; count++)
{
i_count=0;
for(i=1; i<N; i++)
{
j_count=0;
for(j=0; j<N; j++)
{
if(j == count) continue;
Asub[i_count][j_count] = A[i][j];
j_count++;
}
i_count++;
}
det += pow(-1, count) * A[0][count] * MatrixDet(N-1,Asub);
}
return det;
}


//--------------------------------------------
// shell sort
//--------------------------------------------

void shellsort(int size, int* A)
{
int i, j, increment;
int temp;
increment = size / 2;

while (increment > 0) {
for (i = increment; i < size; i++) {
j = i;
temp = A[i];
while ((j >= increment) && (A[j-increment] > temp)) {
A[j] = A[j - increment];
j = j - increment;
}
A[j] = temp;
}

if (increment == 2)
increment = 1;
else
increment = (unsigned int) (increment / 2.2);
}
}

//--------------------------------------------
// gnu quick sort
// (0ptional)
//--------------------------------------------

int compare_int (const int *a, const int *b)
{
int temp = *a - *b;

if (temp > 0) return 1;
else if (temp < 0) return -1;
else return 0;
}

// gnu qsort:
// void qsort (void *a , size_a count, size_a size, compare_function)
// gnu qsort call for a[500] array of int:
// qsort (a , 500, sizeof(a), compare_int)



//--------------------------------------------
// benchmark test procedures
//--------------------------------------------


int test_Int_Add() {
int i=1, j=11, k=112, l=1111, m=11111, n=-1, o=-11, p=-111, q=-1112, r=-11111;
int x;
volatile long s=0;
for(x=0;x<10000;++x) {
s+=i; s+=j; s+=k; s+=l; s+=m; s+=n; s+=o; s+=p; s+=q; s+=r;
}
return s;
}



long test_Int_Mult() {
int x,y;
volatile long s;

for(y=0;y<2000;++y) {
s=1;
for(x=1;x<=13;++x) { s*=x;}
for(x=13;x>0;--x) { s/=x;}

}
return s;
}


#define PI M_PI


float test_float_math() {

volatile float s=PI;
int y;

for(y=0;y<5000;++y) {
s*=sqrt(s);
s=sin(s);
s*=cos(10.5*s);
s=sqrt(s);
s=exp(s);
}
return s;
}


long test_rand_MT(){
volatile unsigned long s;
int y;

for(y=0;y<5000;++y) {
s=randM()%10001;
}
return s;
}


float test_matrix_math() {
int x;

double A[2][2], B[2][2], C[2][2];
double O[3][3], T[3][3];
unsigned long s;

for(x=0;x<250;++x) {

A[0][0]=1; A[0][1]=3;
A[1][0]=2; A[1][1]=4;

B[0][0]=10; B[0][1]=30;
B[1][0]=20; B[1][1]=40;

MatrixMatrixMult(2,2,2, A,B,C);

A[0][0]=1; A[0][1]=3;
A[1][0]=2; A[1][1]=4;

MatrixDet(2, A);

O[0][0]=1; O[0][1]=4; O[0][2]=7;
O[1][0]=2; O[1][1]=5; O[1][2]=8;
O[2][0]=3; O[2][1]=6; O[2][2]=9;

MatrixDet(3, O);

}

s=(O[0][0]*O[1][1]*O[2][2]);
return s;
}



// for array copy using void *memcpy(void *dest, const void *src, size_t n);

long test_Sort(){
unsigned long s;
int y, i;
int t[500];

for(y=0;y<30;++y) {
memcpy(t, a, sizeof(a));
shellsort(500, t);

memcpy(t, a, sizeof(b));
shellsort(500, t);

memcpy(t, a, sizeof(c));
shellsort(500, t);
}

return y;
}



long test_TextOut(){

int y;
char buf[120];

for(y=0;y<20;++y) {
LcdClearDisplay();
sprintf (buf, "%3d %4d int_Add", 0, 1000); LcdText(1, 0,10, buf);
sprintf (buf, "%3d %4d int_Mult", 1, 1010); LcdText(1, 0,20, buf);
sprintf (buf, "%3d %4d float_op", 2, 1020); LcdText(1, 0,30, buf);
sprintf (buf, "%3d %4d randomize", 3, 1030); LcdText(1, 0,40, buf);
sprintf (buf, "%3d %4d matrx_algb", 4, 1040); LcdText(1, 0,50, buf);
sprintf (buf, "%3d %4d arr_sort", 5, 1050); LcdText(1, 0,60, buf);
sprintf (buf, "%3d %4d displ_txt", 6, 1060); LcdText(1, 0,70, buf);
sprintf (buf, "%3d %4d testing...", 7, 1070); LcdText(1, 0,80, buf);

}
return 99;
}


long test_graphics(){
int x=88, y;
for(y=0;y<100;++y) {

LcdClearDisplay();

CircleOut(50, 40, 10);
CircleOutEx(30, 24, 10, DRAW_OPT_FILL_SHAPE);
LineOut(10, 10, 60, 60);
LineOut(50, 20, 90, 70);
RectOut(20, 20, 40, 40);
RectOutEx(65, 25, 20, 30, DRAW_OPT_FILL_SHAPE);
EllipseOut(70, 30, 15, 20);

}
return y;
}


inline void displayValues() {

char buf[120];

sprintf (buf, "%3d %4d int_Add", 0, runtime[0]); LcdText(1, 0,10, buf);
sprintf (buf, "%3d %4d int_Mult", 1, runtime[1]); LcdText(1, 0,20, buf);
sprintf (buf, "%3d %4d float_op", 2, runtime[2]); LcdText(1, 0,30, buf);
sprintf (buf, "%3d %4d randomize", 3, runtime[3]); LcdText(1, 0,40, buf);
sprintf (buf, "%3d %4d matrx_algb", 4, runtime[4]); LcdText(1, 0,50, buf);
sprintf (buf, "%3d %4d arr_sort", 5, runtime[5]); LcdText(1, 0,60, buf);
sprintf (buf, "%3d %4d displ_txt", 6, runtime[6]); LcdText(1, 0,70, buf);
sprintf (buf, "%3d %4d graphics", 7, runtime[7]); LcdText(1, 0,80, buf);
}


void Handler(int sig) // fix ?
{
//printf("handler %d\n", sig);
}

int main(){

unsigned long time0, x, y;
float s;
char buf[120];
int i;

SetTimerCallback(ti1sec, &Handler);

ClearTimer(0);
ClearTimerMS(0);

ButtonLedInit();
LcdInit();
LcdClean();


LcdText(1, 0,10, "hw brickbench");
LcdText(1, 0,20, "(C)H.Wunder 2013");
LcdText(1, 0,50, "initializing...");

for(y=0;y<500;++y) {
a[y]=randM()%30000; b[y]=randM()%30000; c[y]=randM()%30000;
}


LcdClearDisplay();

time0= TimerMS(0);;
s=test_Int_Add();
runtime[0]=TimerMS(0)-time0;
sprintf (buf, "%3d %4d int_Add", 0, runtime[0]); LcdText(1, 0,10, buf);

time0=TimerMS(0);
s=test_Int_Mult();
runtime[1]=TimerMS(0)-time0;
sprintf (buf, "%3d %4d int_Mult", 0, runtime[1]); LcdText(1, 0,20, buf);

time0=TimerMS(0);
s=test_float_math();
runtime[2]=TimerMS(0)-time0;
sprintf (buf, "%3d %4d float_op", 0, runtime[2]); LcdText(1, 0,30, buf);

time0=TimerMS(0);
s=test_rand_MT();
runtime[3]=TimerMS(0)-time0;
sprintf (buf, "%3d %4d randomize", 0, runtime[3]); LcdText(1, 0,40, buf);

time0=TimerMS(0);
s=test_matrix_math();
runtime[4]=TimerMS(0)-time0;
sprintf (buf, "%3d %4d matrx_algb", 0, runtime[4]); LcdText(1, 0,50, buf);


time0=TimerMS(0);
s=test_Sort();
runtime[5]=TimerMS(0)-time0;
sprintf (buf, "%3d %4d arr_sort", 0, runtime[5]); LcdText(1, 0,60, buf);

time0=TimerMS(0);
s=test_TextOut();
runtime[6]=TimerMS(0)-time0;
LcdClearDisplay();
displayValues();

time0=TimerMS(0);
s=test_graphics();
runtime[7]=TimerMS(0)-time0;
LcdClearDisplay();
displayValues();


LcdText(1, 0,100, "cont: press btn < LEFT...");

while(ButtonWaitForAnyPress(100) != BUTTON_ID_LEFT);

LcdClearDisplay();
y=0;
for(x=0;x<8;++x) {y+= runtime[x];}

sprintf (buf, "gesamt ms: %d ", y); LcdText(1, 0,10, buf);
sprintf (buf, "benchmark: %d ", 50000000/y ); LcdText(1, 0,20, buf);

LcdText(1, 0,40, "quit: press btn < LEFT..."); // to be fixed ! <<<<<<<<< no reaction, just for left + ESC !

while(ButtonWaitForAnyPress(100) != BUTTON_ID_LEFT);

LcdExit();
ButtonLedExit();
return 1;

}

shedepe
02.12.2014, 23:21
Das was du suchst wurde bereits im Raspberry Pi Forum gemacht:
http://www.raspberrypi.org/forums/viewtopic.php?f=81&t=25418

Wie wäre es ansonsten, dass du einen funktionierenden C Referenz Code implementierst den man dir dann nach Java oder Python porten kann ?

HaWe
03.12.2014, 07:37
nein danke, ich will ja den RPi auch mit den ganzen anderen Plattformen vergleichen können, für die bereits Messergebnisse existieren (s. Tabelle).
Er wird inzwischen auch von EV3-Software- und VM- Entwicklern (RobotC, Mono/C#, leJOS/Java) benutzt als Vergleich und zur Performanceoptimierung.
Ich selber besitze aber auch noch gar keinen RPi, es soll ja zur Kaufentscheidung dienen.

(ps: und mein Benchmark testet ja auch viel differenzierter in viel mehr Einzeltests in einer viel größeren Bandbreite an Rechenoperationen und Funktionen als nur dieses Primzahlending in deinem Link; andererseits ist mein Referenzcode ja bereits gpp C/C++, wie man es auch mit Eclipse auf Linux-Plattformen benutzt. )

shedepe
03.12.2014, 08:48
Was willst du überhaupt alles Benchmarken ? Nur Arm CPUs oder auch 8bit Prozessoren ? Worauf kommt es dir bei der Kaufentscheidung an ?
Aus der Erfahrung kann ich auch sagen, dass man nur selten wirklich jedes quäntchen Performance rauskitzelt (Einfach weil es abartig Zeitaufwändig ist) oder gar die Programmiersprache nach der Performance wählt. Meistens ist es sinnvoller man wählt die Programmiersprache nach den benötigten Libraries aus und danach was man besser programmieren kann.

Desweiteren versuchst du (soweit ich das erkennen kann) gerade auch Plattformen auf denen ein komplettes Betriebssystem läuft mit Plattformen zu vergleichen die kein oder nur ein sehr rudimentäres Betriebssystem haben. Worauf ich letztendlich hinauswill. Selbst mal wenn du den Benchmark portest, die Frage ist ob du ein aussagekräftiges Ergebnis bekommen wirst und ob du wirklich etwas damit anfangen kannst.

HaWe
03.12.2014, 09:06
ich nutze es halt zur Kaufentscheidung. Es sind typische Operationen wie ich und andere sie öfters nutzen zu unterschiedlichsten Zwecken.
Insbesondere geht es um den Unterschied C vs. Python vs. Java, und auch vs. EV3 und vs. Arduino Due.
Auch der EV3 ist 32-bit ARM- und Linux-basiert (TI oder Debian).
Es muss ja nicht DICH interessieren, aber MICH interessiert es.
:cool:

shedepe
03.12.2014, 10:52
So hätte ich das jetzt nicht formuliert. Schließlich will man ja vor dem Kauf durchaus wissen, was man sich kauft. Die Frage ist aber echt wie aussagekräftig ein Benchmark ist. Für vergleichbare Ergebnisse würde ich stark eher zu Standard benchmark Tools wie sysbench oder stress raten ( Nachteil -> verschiedene Programmiersprachen werden nicht verglichen -> darauf gehe ich aber noch ein)
Ich könnte dir aber den Benchmark in C auf nem Raspberry ausführen wenn du darauf bestehst und wenn du ihn selber anpasst und durch einen crosscompiler schiebst. (Anpassen ist echt einfach. Alle Hardware spezifischen Sachen entfernen bzw. die Timer durch ctime ersetzen)
Für den Unterschied C - Java - Python - die werden kaum anderes sein als für andere Plattformen wobei man dran denken sollte, dass Java durch wenig Ram auch ausgebremst werden kann. Aber um für Geschwindigkeitsunterschiede zwischen einzelnen Programmiersprachen akzeptable Benchmarks zuerstellen braucht es mehr Zeit als die meisten Leute in einem Forum investieren wollen, über solche Themen wurden schon ganze wissenschaftliche Arbeiten verfasst ( http://www.azulsystems.com/blog/cliff/2009-09-06-java-vs-c-performanceagain ). Die Python Entwickler äußern sich sogar direkt zur Performance : https://wiki.python.org/moin/PythonSpeed -> Man kann z.B. C -Module in Python verwenden die eben stark optimiert wurden. Reine CPU Intensive Operationen wie dein Benchmark sie ausführt werden aber kaum feststellbare Unterschiede ergeben.
Deine Testfunktionen testen vorallem die CPU Leistung und allerhöchstens noch die Zugriffgeschwindigkeit auf den L1 Cache. Zudem muss man auch noch beachten, dass einige Raspian Distros anscheinend Probleme mit der Detection des L1 Caches haben. Interessant für eine allgemeine Leistungsaussage sind jedoch noch viel mehr Daten: Speicherzugriffsraten, Zugriffszeiten, Transferzeiten zur GPU. Hier kommt es auch stark auf die später geplante Anwendung an wie diese gewisse Zugriffe macht, in wiefern sie optimiert wurde, ob sie von der Hardwarebeschleunigung profitieren kann oder nicht. Dies ist eben gerade interessant wenn man Java und Python verwendet. Hier kann man z.B. bei vielen IO Zugriffen in eine Performancefalle laufen -> kann man aber bei python durch bestimmte Optimierungen gut umgehen.

Peter(TOO)
03.12.2014, 12:58
Hallo,

Man muss auch sehr aufpassen, WAS man da misst!

Bei einer CPU ohne Fliesskomma-Einheit, testet ein Fliesskommatest nur das Emulationspaket des Compilers. Emulierte Fliesskomma-Operationen sind in der Grössenordnung 100x langsamer als eine Hardware-Einheit. Die Frage ist dann auch noch, welches Fliesskomma-Format verwendet wird!

Und nicht vergessen, die Steigerung von Lüge:
Lüge - Meineid- Statistik - Benchmark


Ein IAR-Konkurrent hatte auch mal seinen Compiler für die H8 von Hitachi mit Benchmarks beworben und wesentlich besser abgeschnitten.
Der Trick war: Nach einem Reset läuft der H8 mit 3 Wait-States, damit er auch mit langsamem Speicher startet. Beim IAR-Paket muss man die Wait-States dann selber hoch setzen, beim Konkurrenten hat das der Compiler automatisch eingefügt (Dann muss man aber mit langsamem Speicher das von Hand ändern, sonst läuft es nicht).
Tja.... Ist auch schon 20 Jahre her ...

MfG Peter(TOO)

HaWe
03.12.2014, 13:15
ich will jetzt nicht über denn Sinn aller Einzeltests diskutieren oder das Gesamtresultat -
der Benchmark misst, was der Benchmark misst.

Zufällig misst er genau das, was mich (und andere) interessiert, und er ist auf mehreren Plattformen etabliert.
Also wird er (zunächst, mittelfristig) so bleiben, und wenn er mal verbessert wird (was ja sein kann), so müssen ntl auch alle Codes für alle anderen Plattformen neu programmiert werden.
Das ist nicht einfach, weil viele Codes von anderen Nutzern stammen, die ich selber gar nicht ändern kann und wo ich auch gar nicht die Plattformen dazu habe und nutze (u.a. C#, Java, RobotC, Toppers C).

Wäre also schön, wenn man als Zusatzplattform für den bestehenden Test auch den RPi hätte mit 2-3 verschiedenen Programmiersprachen.
V.a. C und Python halt, ggf auch Java.

ps,
wenn man sich an die C-Vorlage hält, insb. was die "volatiles" angeht, wird hier schon was vergleichbares herauskommen.
Außerdem kann ja jeder dann den entspr. angepassten Code selber testen und auf Fehler oder Cheats überprüfen (wer will und mag).

pps,
C-Module in Python gehen ntl normalerweise nicht, es sollen ja die "nackten" Codes verglichen werden. Es dürfen in einigen Fällen (z.B. sort) auch library-Implementationen verwendet werden.
Genau das soll ja der Test widerspiegeln:
sowohl einfache elementare und dann zunehmend kompliziertere bis hin zu hochkomplexen Berechnungen und Display-Output Operationen.
Jeder kann sich da übrigens für sich selber herausfiltern, was ihm persönlich am wichtigsten ist.

Für mich persönlich ist das:
einfach alles. ;)

peterfido
03.12.2014, 15:22
Vergiss die Benchmarkgeschichte. Die sagt nichts aus. Bei dem nächsten Update oder auch nur einer anderen kleinen Lib kann es schon ganz anders aussehen. Vom Multitasking, welches mehr oder weniger bremsen kann, ganz zu schweigen.

Sag einfach (oder besser umfangreich), was Du mit dem Raspi vorhast und evtl. hat es schon jemand so oder ähnlich gemacht und kann Dir seine Erfahrungen mitteilen.

Edit:
Oder kauf Dir einfach einen. Für ~30 Euro kann man da nichts falsch machen, wenn man Bastel- Programmierfreund ist sowieso nicht..

HaWe
03.12.2014, 15:53
ich würde gern die Benchmarks sehen, insb. den Vergleich RPi mit Python und mit ANSI-C und ggf. Java.
Punkt.

Valen
05.12.2014, 22:22
Das hier schon gesehen?


http://www.roylongbottom.org.uk/Raspberry%20Pi%20Benchmarks.htm


Es ist aber nicht ein verlgleich von MCUs, sondern Klein-computer Prozessoren.

HaWe
05.12.2014, 22:46
nicht speziell diese Übersicht, aber ähnliche, weniger umfangreiche.
Alle testen aber weder EV3s noch NXTs noch Arduino Megas noch Arduino Dues.
Mit geht es um den direkten Vergleich mit ein und demselben Benchmark für diese vorgenannten Hardware- und Software-Plattformen und auch für RPi (und später auch BBB).
Welcher jetzt besser sein könnte, steht gar nicht zur Debatte - jeder hat seine spezielle Berechtigung.

Aber gerade wegen der Lego-MCUs nehme ich meinen Benchmark als Vergleichsbasis, die auch die detaillierten Stärken und Schwächen einiger spezieller Plattformen besonders unter die Lupe nimmt (z.B. bit/byte-shift, mehrdim. Arrays rekursiv und array sort., daneben Display und "Programmier-Environment")

- - - Aktualisiert - - -

also... -
mich würde jetzt wirklich mal interessieren, wie schnell der RPI bei benchmark-Tests abschneidet, und zwar
1x unter C
1x unter Python - und, wenn möglich,
1x unter Java.


Einen Benchmark Test für verschiedene MCUs habe ich schon - jetzt müsste man ihn nur für den RPi anpassen.

http://www.mindstormsforum.de/viewtopic.php?f=71&t=8095&start=60#p64772


Setup + design:
This benchmark test is including several test functions for different individual computational patterns:
- simple basic integer arithmetics (addition/substraction, multiplication/division),
- real and transcendental float arithmetic functions (sqrt,sin,cos, exp), preferably 64bit double (=> bonus points)
- advanced matrix algebra for more-dim array manipulation (matrix product + determinant, built-in or imported) (genuine multi-dim arrays => bonus points)
- pseudo random number generator (Mersenne Twister): low-level bit- and-byte-operations like AND, XOR, SHIFT-left/right
- quick high-level sort algorithm for arrays[500] (preferably Shellsort, built-in or imported),
- a text-output and a 2D-graphics test for graph + shape + fill computation and lcd output stressing.

the latest brickbench test enhancement also takes programming-environments into account, i.e.
- available memory, networking/chaining abilities,
- variable types (e.g. for double precision fp and matrices/more-dim arrays),
- recursions,
- multithreading support,
- and, last but not least, the wholeness of API functions for hardware (screen, and attached sensors and motors), and the IDE.


Wenn Python nämlich WIRKLICH geschwindigkeitsmäßig an C herankommt, wäre es ja wirklich eine Alternative.
Wer hat Lust und traut sich?

Der C-Code ist vorhanden und sicher leicht portierbar, mit Python und Java kenne ich mich (noch) nicht aus.
Den Grafik-Teil kann man notfalls (erstmal) weglassen und evtl später nachreichen.

Hier ist der C-Referenz-Code (danach auch einige Adaptationen, u.a. für Java, aber hier ist ein kleiner Fehler drin) -

http://www.mindstormsforum.de/viewtopic.php?f=71&t=8095&start=60#p64494



// HaWe brickbench
// benchmark test for NXT/EV3 and similar Micro Controllers
// PL: gpp CSLite C/C++, C-API and BCC by John Hansen
// Autor: (C) Helmut Wunder 2013,2014
// freie Verwendung für private Zwecke
// für kommerzielle Zwecke nur nach Genehmigung durch den Autor.
// protected under the friendly Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
// http://creativecommons.org/licenses/by-nc-sa/3.0/
// version 1.08.2

#include <stdio.h>
#include <math.h>
#include <fcntl.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/ioctl.h>

#include "lms2012.h"
#include "ev3_button.h"
#include "ev3_lcd.h"
#include "ev3_constants.h"
#include "ev3_command.h"
#include "ev3_timer.h"
#include "ev3_lcd.h"
#include "ev3_sound.h"
#include "ev3_output.h"


unsigned long runtime[8];

int a[500], b[500], c[500], t[500];


//--------------------------------------------
// Mersenne Twister
//--------------------------------------------

unsigned long randM(void) {
const int M = 7;
const unsigned long A[2] = { 0, 0x8ebfd028 };

static unsigned long y[25];
static int index = 25+1;

if (index >= 25) {
int k;
if (index > 25) {
unsigned long r = 9, s = 3402;
for (k=0 ; k<25 ; ++k) {
r = 509845221 * r + 3;
s *= s + 1;
y[k] = s + (r >> 10);
}
}
for (k=0 ; k<25-M ; ++k)
y[k] = y[k+M] ^ (y[k] >> 1) ^ A[y[k] & 1];
for (; k<25 ; ++k)
y[k] = y[k+(M-25)] ^ (y[k] >> 1) ^ A[y[k] & 1];
index = 0;
}

unsigned long e = y;
e ^= (e << 7) & 0x2b5b2500;
e ^= (e << 15) & 0xdb8b0000;
e ^= (e >> 16);
return e;
}

//--------------------------------------------
// Matrix Algebra
//--------------------------------------------

// matrix * matrix multiplication (matrix product)

void MatrixMatrixMult(int N, int M, int K, double A[][M], double B[][K], double C[][K]){
int i, j, s; // matrix A: N x M // B: M x K // C: N x K
for (i=0; i<N; ++i) {
for (j=0; j<K; ++j) {
C[i][j]=0;
for (s=0; s<M; ++s) {
C[i][j]=C[i][j] + A[i][s]*B[s][j];
}
}
}
}


// matrix determinant

double MatrixDet(int N, double A[N][N])
{
int i,j,i_count,j_count, count=0;
double Asub[N-1][N-1], det=0;

if(N==1) return A[0][0];
if(N==2) return (A[0][0]*A[1][1] - A[0][1]*A[1][0]);

for(count=0; count<N; count++)
{
i_count=0;
for(i=1; i<N; i++)
{
j_count=0;
for(j=0; j<N; j++)
{
if(j == count) continue;
Asub[i_count][j_count] = A[i][j];
j_count++;
}
i_count++;
}
det += pow(-1, count) * A[0][count] * MatrixDet(N-1,Asub);
}
return det;
}


//--------------------------------------------
// shell sort
//--------------------------------------------

void shellsort(int size, int* A)
{
int i, j, increment;
int temp;
increment = size / 2;

while (increment > 0) {
for (i = increment; i < size; i++) {
j = i;
temp = A[i];
while ((j >= increment) && (A[j-increment] > temp)) {
A[j] = A[j - increment];
j = j - increment;
}
A[j] = temp;
}

if (increment == 2)
increment = 1;
else
increment = (unsigned int) (increment / 2.2);
}
}

//--------------------------------------------
// gnu quick sort
// (0ptional)
//--------------------------------------------

int compare_int (const int *a, const int *b)
{
int temp = *a - *b;

if (temp > 0) return 1;
else if (temp < 0) return -1;
else return 0;
}

// gnu qsort:
// void qsort (void *a , size_a count, size_a size, compare_function)
// gnu qsort call for a[500] array of int:
// qsort (a , 500, sizeof(a), compare_int)



//--------------------------------------------
// benchmark test procedures
//--------------------------------------------


int test_Int_Add() {
int i=1, j=11, k=112, l=1111, m=11111, n=-1, o=-11, p=-111, q=-1112, r=-11111;
int x;
volatile long s=0;
for(x=0;x<10000;++x) {
s+=i; s+=j; s+=k; s+=l; s+=m; s+=n; s+=o; s+=p; s+=q; s+=r;
}
return s;
}



long test_Int_Mult() {
int x,y;
volatile long s;

for(y=0;y<2000;++y) {
s=1;
for(x=1;x<=13;++x) { s*=x;}
for(x=13;x>0;--x) { s/=x;}

}
return s;
}


#define PI M_PI


float test_float_math() {

volatile float s=PI;
int y;

for(y=0;y<5000;++y) {
s*=sqrt(s);
s=sin(s);
s*=cos(10.5*s);
s=sqrt(s);
s=exp(s);
}
return s;
}


long test_rand_MT(){
volatile unsigned long s;
int y;

for(y=0;y<5000;++y) {
s=randM()%10001;
}
return s;
}


float test_matrix_math() {
int x;

double A[2][2], B[2][2], C[2][2];
double O[3][3], T[3][3];
unsigned long s;

for(x=0;x<250;++x) {

A[0][0]=1; A[0][1]=3;
A[1][0]=2; A[1][1]=4;

B[0][0]=10; B[0][1]=30;
B[1][0]=20; B[1][1]=40;

MatrixMatrixMult(2,2,2, A,B,C);

A[0][0]=1; A[0][1]=3;
A[1][0]=2; A[1][1]=4;

MatrixDet(2, A);

O[0][0]=1; O[0][1]=4; O[0][2]=7;
O[1][0]=2; O[1][1]=5; O[1][2]=8;
O[2][0]=3; O[2][1]=6; O[2][2]=9;

MatrixDet(3, O);

}

s=(O[0][0]*O[1][1]*O[2][2]);
return s;
}



// for array copy using void *memcpy(void *dest, const void *src, size_t n);

long test_Sort(){
unsigned long s;
int y, i;
int t[500];

for(y=0;y<30;++y) {
memcpy(t, a, sizeof(a));
shellsort(500, t);

memcpy(t, a, sizeof(b));
shellsort(500, t);

memcpy(t, a, sizeof(c));
shellsort(500, t);
}

return y;
}



long test_TextOut(){

int y;
char buf[120];

for(y=0;y<20;++y) {
LcdClearDisplay();
sprintf (buf, "%3d %4d int_Add", 0, 1000); LcdText(1, 0,10, buf);
sprintf (buf, "%3d %4d int_Mult", 1, 1010); LcdText(1, 0,20, buf);
sprintf (buf, "%3d %4d float_op", 2, 1020); LcdText(1, 0,30, buf);
sprintf (buf, "%3d %4d randomize", 3, 1030); LcdText(1, 0,40, buf);
sprintf (buf, "%3d %4d matrx_algb", 4, 1040); LcdText(1, 0,50, buf);
sprintf (buf, "%3d %4d arr_sort", 5, 1050); LcdText(1, 0,60, buf);
sprintf (buf, "%3d %4d displ_txt", 6, 1060); LcdText(1, 0,70, buf);
sprintf (buf, "%3d %4d testing...", 7, 1070); LcdText(1, 0,80, buf);

}
return 99;
}


long test_graphics(){
int x=88, y;
for(y=0;y<100;++y) {

LcdClearDisplay();

CircleOut(50, 40, 10);
CircleOutEx(30, 24, 10, DRAW_OPT_FILL_SHAPE);
LineOut(10, 10, 60, 60);
LineOut(50, 20, 90, 70);
RectOut(20, 20, 40, 40);
RectOutEx(65, 25, 20, 30, DRAW_OPT_FILL_SHAPE);
EllipseOut(70, 30, 15, 20);

}
return y;
}


inline void displayValues() {

char buf[120];

sprintf (buf, "%3d %4d int_Add", 0, runtime[0]); LcdText(1, 0,10, buf);
sprintf (buf, "%3d %4d int_Mult", 1, runtime[1]); LcdText(1, 0,20, buf);
sprintf (buf, "%3d %4d float_op", 2, runtime[2]); LcdText(1, 0,30, buf);
sprintf (buf, "%3d %4d randomize", 3, runtime[3]); LcdText(1, 0,40, buf);
sprintf (buf, "%3d %4d matrx_algb", 4, runtime[4]); LcdText(1, 0,50, buf);
sprintf (buf, "%3d %4d arr_sort", 5, runtime[5]); LcdText(1, 0,60, buf);
sprintf (buf, "%3d %4d displ_txt", 6, runtime[6]); LcdText(1, 0,70, buf);
sprintf (buf, "%3d %4d graphics", 7, runtime[7]); LcdText(1, 0,80, buf);
}


void Handler(int sig) // fix ?
{
//printf("handler %d\n", sig);
}

int main(){

unsigned long time0, x, y;
float s;
char buf[120];
int i;

SetTimerCallback(ti1sec, &Handler);

ClearTimer(0);
ClearTimerMS(0);

ButtonLedInit();
LcdInit();
LcdClean();


LcdText(1, 0,10, "hw brickbench");
LcdText(1, 0,20, "(C)H.Wunder 2013");
LcdText(1, 0,50, "initializing...");

for(y=0;y<500;++y) {
a[y]=randM()%30000; b[y]=randM()%30000; c[y]=randM()%30000;
}


LcdClearDisplay();

time0= TimerMS(0);;
s=test_Int_Add();
runtime[0]=TimerMS(0)-time0;
sprintf (buf, "%3d %4d int_Add", 0, runtime[0]); LcdText(1, 0,10, buf);

time0=TimerMS(0);
s=test_Int_Mult();
runtime[1]=TimerMS(0)-time0;
sprintf (buf, "%3d %4d int_Mult", 0, runtime[1]); LcdText(1, 0,20, buf);

time0=TimerMS(0);
s=test_float_math();
runtime[2]=TimerMS(0)-time0;
sprintf (buf, "%3d %4d float_op", 0, runtime[2]); LcdText(1, 0,30, buf);

time0=TimerMS(0);
s=test_rand_MT();
runtime[3]=TimerMS(0)-time0;
sprintf (buf, "%3d %4d randomize", 0, runtime[3]); LcdText(1, 0,40, buf);

time0=TimerMS(0);
s=test_matrix_math();
runtime[4]=TimerMS(0)-time0;
sprintf (buf, "%3d %4d matrx_algb", 0, runtime[4]); LcdText(1, 0,50, buf);


time0=TimerMS(0);
s=test_Sort();
runtime[5]=TimerMS(0)-time0;
sprintf (buf, "%3d %4d arr_sort", 0, runtime[5]); LcdText(1, 0,60, buf);

time0=TimerMS(0);
s=test_TextOut();
runtime[6]=TimerMS(0)-time0;
LcdClearDisplay();
displayValues();

time0=TimerMS(0);
s=test_graphics();
runtime[7]=TimerMS(0)-time0;
LcdClearDisplay();
displayValues();


LcdText(1, 0,100, "cont: press btn < LEFT...");

while(ButtonWaitForAnyPress(100) != BUTTON_ID_LEFT);

LcdClearDisplay();
y=0;
for(x=0;x<8;++x) {y+= runtime[x];}

sprintf (buf, "gesamt ms: %d ", y); LcdText(1, 0,10, buf);
sprintf (buf, "benchmark: %d ", 50000000/y ); LcdText(1, 0,20, buf);

LcdText(1, 0,40, "quit: press btn < LEFT..."); // to be fixed ! <<<<<<<<< no reaction, just for left + ESC !

while(ButtonWaitForAnyPress(100) != BUTTON_ID_LEFT);

LcdExit();
ButtonLedExit();
return 1;

}



[I](edit: wem die Arduino-Portierung besser als Basis gefällt, kann stattdessen auch diese verwenden: http://www.mindstormsforum.de/viewtopic.php?f=71&t=8095&start=60#p64772 - sie enthält allerdings nicht den Display -Test-Teil, da ich selber noch kein Arduino-TFT mit entspr. Libs besitze). Diese Portierung stammt von mir selber und ist ansonsten 100% vergleichbar.

Weitere Portierungen, z.B. für C# und Java, finden sich oberhalb oder unterhalb dieses Links - diese stammen allerdings nicht von mir selber und können durchaus Fehler enthalten. Für Java wurde das berichtet, aber noch nicht korrigiert. Hier würde Java nach Berichtigung sogar etwas besser abschneiden.

Manf
08.12.2014, 19:41
Ich sehe auch mit Bedauern, dass man hier nicht richtig weiterkommt, immerhin sind sehr erfahrene Forenmitglieder an der Diskussion beteiligt.
Die Härte der Diskussion ist etwas über dem sinnvollen Level, es ufert nicht wirklich aus, aber es geht eben auch nicht weiter.

Fast hätte ich schon vorgeschlagen einen besonders einfachen wenn auch nicht zu aussagekräftigen Benchmark zu versuchen, aber da ist mir peterfido zuvor gekommen, der das ganze dann schon wieder sehr ironisch aufbereitet hat.

Manf (als Moderator)



Lassen wir das mal so stehen, mit der Option dass der TO auch einen neuen Thread aufmachen kann.
Wenn dort nichts kommt dann eben nicht.
Das Recht auf einen sachlichen Umgang mit dem jeweiligen Thema soll man ja haben, (auch wenn es nicht lösbar sein sollte).

HaWe
09.12.2014, 07:50
@manf: vielen Dank

übrigens wofür der RPi mit Python gedacht war:
spezielle Rechentests weil ich solche Art von Berechnungen ständig für viel Arithmetik und Algebra benutze (Anwendungsprogramme: inverse Kinematik, Navigation, FFT, Kalman-Filter, Monte-Carlo-Filter, Astar, Neuronale Netze), als schnelleren und leistungsfähigeren Ersatz für meine NXTs und Arduino Dues, auf denen diese Anwendungsprogramme nur teilw. oder gar nicht laufen wegen viel zu geringer Geschwindigkeit und viel zuwenig RAM und/oder Flash.

Technipion
10.12.2014, 08:24
Hallo Leute,
ich finde es auch nicht gut wenn respektlos miteinander umgegangen wird, das möchte ich nur beiden Seiten gesagt haben. Mich stört es nicht einmal, dass die "bösen" Beiträge wieder entfernt wurden ;)
Aber nun zurück zu HaWes Frage:
Das hier ist genau der Satz, auf den wir alle gewartet hatten:

übrigens wofür der RPi mit Python gedacht war:
spezielle Rechentests weil ich solche Art von Berechnungen ständig für viel Arithmetik und Algebra benutze (Anwendungsprogramme: inverse Kinematik, Navigation, FFT, Kalman-Filter, Monte-Carlo-Filter, Astar, Neuronale Netze), als schnelleren und leistungsfähigeren Ersatz

Jetzt können wir dir präzise Antworten, ganz ohne Benchmark :cool:
In der Regel (das trifft auch auf den RPI zu) ist Python etwa um einen Faktor 1,5 bis 10 langsamer als C. Das kommt einfach daher wie der Python-Interpreter funktioniert. Bei reinen Anwendungsprogrammen ist das allerdings kein Problem, die Performance ist hier meist zweitrangig (so stört es z.B. niemanden, dass die Youtube-Server fast komplett mit Python gescriptet sind). Google setzt übrigens Python ein, weil es durchaus seine Stärken hat (@HaWe: Falls du Python lernst, und dir hierfür ein gutes Buch zulegst, werden die Vorteile von Python sicherlich deutlich).
Eine dieser Stärken ist die hohe Modularität, und genau hier kommen wir zum Thema:
Schreibst du rechenintensive Anwendungen, bei denen es um Performance geht, dann skriptest du diese nicht in Python, sondern lässt die Rechnungen von einem Modul (C-like: Bibliothek) ausführen. Bei dir wäre wohl numpy/scipy (http://www.scipy.org/) angebracht. Diese Module sind selbst in C/C++ geschrieben, Python ruft lediglich die bereits compilierten Funktionen auf. Dadurch erreichst du - zumindest bei den Berechnungen - C-Geschwindigkeit. Normalerweise ist Python mit externem C-Modul bereits schnell genug für Game-Engines (siehe http://www.panda3d.org/). Die richtigen Hardcore-Bastler könnten die Performance mit PyPy (http://pypy.org/) bzw. RPython allerdings noch weiter steigern. Bei stackoverflow hatten sie da mal einen schönen Vergleich gezogen (http://stackoverflow.com/questions/6964392/speed-comparison-with-project-euler-c-vs-python-vs-erlang-vs-haskell).
Dein Benchmark hätte dir auf dem RPI mit Sicherheit die gleichen relativen Laufzeiten ausgegeben.
Falls du dich entscheiden solltest dein Programm in Python zu Schreiben, und es dann nicht schnell genug laufen sollte, dann kannst du dich immernoch an ein Programmierforum wenden und den Code optimieren. Grundsätzlich kann man jedes Programm in jeder Sprache realisieren...

Grüße Technipion

HaWe
10.12.2014, 10:08
dankeschön für die Klarstellung, aber ich möchte nicht vorwiegend auf externe libs zurückgreifen müssen, das ist mir zu umständlich und damit kenne ich mich erst recht nicht aus. Außerdem muss man da sicher wieder auf Linux-Shell-Ebene rummanipulieren oder sich sogar selber mit C-Compilern, Eclipse unf Makefile rumquälen:
Bei einfachen Array-Sortieralgorithmen wie qsort geht das ja gerade noch, wen man sie schon auf dem Flash oder der SD drauf hat und sie nur noch includen muss, aber alles andere müsste "nativ" funktionieren...

Schließlich schreibe ich ja meine eigenen Routinen je nach Bedarf mal so, mal so, und ich muss im Quellcode die Möglichkeit haben, einfach mal eben die einen oder anderen Berechnungen runterschreiben zu können.

Daher wäre zur Beurteilung der einzelnen RPi-Fähigkeiten und Schwachstellen eben doch der Benchmark (C / Python / Java) interessant gewesen, ganz unabhängig von späteren konkreten Projekten.