einfacher CPU Geschwindigkeitstest vom Einplatinencomputer: pi berechnen mit bc

HITCHER_I

Commodore
Registriert
Okt. 2006
Beiträge
4.803
bc ist ein Taschenrechner mit beliebiger Genauigkeit, und damit kann man die Kreiszahl pi ausrechnen,
indem man zB. arctan(1)*4 berechnet.
https://linux.die.net/man/1/bc

Nur ist der normale bc vom manpage oben ziemlich alt, und langsam,
darum nehmen wir lieber den neuen vom Gavin Howard, der den weiter optimiert und beschleunigt hat.
https://github.com/gavinhoward/bc/blob/master/README.md Nicht vergessen mit configure -O3 zu configurieren.

Und die Formel für pi= arctan(1)*4 ist auch überholt, da gibt es eine etwas schnellere.
pi=24*atan(1/8)+8*atan(1/57)+4*atan(1/239)

Der Pi4 4GB@2 GHz schafft 100.000 Stellen nun in 34m, 22s.
OS ist Ubuntu 21.10 ARM64 - raspi.

Code:
$ time echo "scale=100000; 24*atan(1/8)+8*atan(1/57)+4*atan(1/239)" | ./bc -l
3.141592653589793238462643383279502884197169399375105820974944592307\
81640628620899862803482534211706798214808651328230664709384460955058\
22317253594081284811174502841027019385211055596446229489549303819644\
...
02212235719254536715191834872587423919410890444115959932760044506556\
20646116465566548759424736925233695599303035509581762617623184956190\
64948396730020377638743693439998294302091470736189479326927624451865\
60239559053705128978163455423320114975994896278424327483788032701418\
67695262118097500640514975588965029300486760520801049153788541390942\
45316917199876289412772211294645682948602814931815602496778879498137\
77216229359437811004448060797672429276249510784153446429150842764520\
00204276947069804177583220909702029165734725158290463091035903784297\
75726517208772447409522671663060054697163879431711968734846887381866\
56751279298575016363411314627530499019135646823804329970695770150789\
337728658035712790913767420805655493624632

real    34m22,038s
user    34m17,482s
sys     0m4,285s
Wer mag, kann das ja mal mit dem alten bc ausprobieren, mir dauert das zu lange.

Zum Vergleich, mit der einfachen Formel und alten bc brauchen 10.000 Stellen schon 3m, 8s,
mit dem neuen bc und selber Formel nur 11,825s.
Code:
$ time echo "scale=10000; 4*a(1)" | bc -l
3.141592653589793238462643383279502884197169399375105820974944592307\
...
91403599895353945909440704691209140938700126456001623742880210927645\
79310657922955249887275846101264836999892256959688159205600101655256\
375676

real    3m7,932s
user    3m7,904s
sys     0m0,027s
$ time echo "scale=10000; 4*atan(1)" | ./bc -l
3.141592653589793238462643383279502884197169399375105820974944592307\
...
91403599895353945909440704691209140938700126456001623742880210927645\
79310657922955249887275846101264836999892256959688159205600101655256\
375676

real    0m11,825s
user    0m11,805s
sys     0m0,023s

edit:
Habe die Dateien nochmal zusammengestellt, mit denen man das am Pi oder anderem ARM SBC testen kann, bc (für ARM64) ist inkludiert. https://www.computerbase.de/forum/attachments/gh-bc-zip.1322742/
 
Zuletzt bearbeitet:
  • Gefällt mir
Reaktionen: ghecko
Was fällt mir zu pi ein?


Alter, aus dem Gedächtnis 100.000 Stellen. Ok, sicher nicht so schnell wie auf dem Raspberry ^^
 
  • Gefällt mir
Reaktionen: HITCHER_I und DJMadMax
@ghecko
Ja, das läuft scheinbar nur singlethread, jedenfalls zeigt htop nur Auslastung auf einem Kern an.

Wobei man das aber noch verbessern können müsste, weil die og. Formel ja aus 3 Teilen besteht.
Die 3 Teile könnte man jeweils mit einem bc berechnen, und dann die Ergebnisse mit einem dritten vierten bc zusammen zählen, alles gleichzeitig.
 
Zuletzt bearbeitet:
Hätte mich auch gewundert wenn das parallelisierbar wäre :D
HITCHER_I schrieb:
Die 3 Teile könnte man jeweils mit einem bc berechnen, und dann die Ergebnisse mit einem dritten bc zusammen zählen.
Der Dritte(vierte?) wartet dann aber auf den längsten Operanten aus den anderen, der dann letztlich die Geschwindigkeit bestimmt. Das beschleunigt das ganze natürlich, ist dann aber doch eher eine SC-Leistung aus einer MC-Belastung. Genauer ist es, das ganze als reine SC-Berechnung laufen zu lassen um die Leistung eines Kerns zu bestimmen.

Oder einfach für jeden Kern dieselbe Instanz und am Ende die Werte vergleichen.
 
Zuletzt bearbeitet:
@ghecko
Wenn zB. 1000.000 Stellen berechnet werden von bc, dann werden scheinbar immer 32 Stellen-Blöcke berechnet, dh. man müsste alle 32 Stellen das Ergebnis in eine Warteschlange weiterreichen können, damit andere Prozesse es weiter verarbeiten können. Man ist zB. bei 10.000 schon fertig berechneten Stellen, die ändern sich danach nicht mehr, wenn die weiteren Stellen zur höheren Genauigkeit berechnet werden, die Änderungen an der Zahl werden also immer kleiner, je länger die Berechnung dauert. Daher könnte man schon auf vorherige Stellen zugreifen, wenn die Berechnung selbst nocht nicht abgeschlossen ist.
Aber mit den beiden Versionen von BC ist das wohl nicht möglich, die geben die Zahl erst aus, wenn sie komplett fertig berechnet ist.

Die einzelnen Teile der Formel zu berechnen dauert auch nicht ca. gleich lang.:mad:

edit:
habe es jetzt aber doch etwas beschleunigen können, indem die 3 Teile gleichzeitig laufen,
nur leider braucht ein Teil davon 2/3 der Gesamtzeit.
Code:
$ time ./bc-pi-test.sh
3.141592653589793238462643383279502884197169399375105820974944592307\
81640628620899862803482534211706798214808651328230664709384460955058\
...
45316917199876289412772211294645682948602814931815602496778879498137\
77216229359437811004448060797672429276249510784153446429150842764520\
00204276947069804177583220909702029165734725158290463091035903784297\
75726517208772447409522671663060054697163879431711968734846887381866\
56751279298575016363411314627530499019135646823804329970695770150789\
337728658035712790913767420805655493624632

real    20m51,634s
user    35m0,324s
sys     0m13,141s

Der Code dazu. Wobei man das geschickter machen könnte, wenn man ein bash-Profi ist.
Code:
$ cat bc-pi1.sh
#!/bin/bash

echo "scale=100000; 24*atan(1/8)" | ./bc -l > TermA

$ cat bc-pi2.sh
#!/bin/bash

echo "scale=100000; 8*atan(1/57)" | ./bc -l > TermB

$ cat bc-pi3.sh
#!/bin/bash

echo "scale=100000; 4*atan(1/239)" | ./bc -l > TermC

$ cat bc-pi-test.sh
#!/bin/bash

./bc-pi1.sh & ./bc-pi2.sh & ./bc-pi3.sh && TermB=$(cat ./TermB) && TermC=$(cat ./TermC) && TermA=$(cat ./TermA) &&  echo "scale=100000; $TermA + $TermB + $TermC" | ./bc -l
 
Zuletzt bearbeitet:
Mein Raspberry Pi 3B+ mit rasbios 32Bit und aktiviertem 64-Bit Kernel (bringt in dem Fall nichts).
32Bit Binary vom Gavin Howard bc:

Code:
$  time echo "scale=100000; 24*atan(1/8)+8*atan(1/57)+4*atan(1/239)" | ./bc -l
3.141592653589793238462643383279502884197169399375105820974944592307\
....
00204276947069804177583220909702029165734725158290463091035903784297\
75726517208772447409522671663060054697163879431711968734846887381866\
56751279298575016363411314627530499019135646823804329970695770150789\
337728658035712790913767420805655493624632

real    520m24.282s
user    519m27.160s
sys     0m47.200s

Gegenüber den og. 34m, 22s ist das ca. 15x langsamer. :o
Der Pi3B+ ist halt auch nicht übertaktet, dh. da spielt die niedrigere Taktfrequenz auch rein,
aber auch 64Bit OS vs. 32Bit OS. Mit 64-Bit OS wäre er vermutlich auch etwas schneller.
 
FX-8300 @3,6/4,2 GHz, Linux x64
Code:
% time echo "scale=100000; 24*atan(1/8)+8*atan(1/57)+4*atan(1/239)" | ./bc -l
...
67695262118097500640514975588965029300486760520801049153788541390942\
45316917199876289412772211294645682948602814931815602496778879498137\
77216229359437811004448060797672429276249510784153446429150842764520\
00204276947069804177583220909702029165734725158290463091035903784297\
75726517208772447409522671663060054697163879431711968734846887381866\
56751279298575016363411314627530499019135646823804329970695770150789\
337728658035712790913767420805655493624632

1273.56s user
1.74s system
99% cpu 21:15.66 total

Da hat man den Vergleich zu einer x86-64 CPU, die einen großen Taktvorteil hat.
Selbe Version bc-5.1.1 Gavin Howard wie oben.
 
Zuletzt bearbeitet:
Anderer Vergleichswert von Fedora x64 v.34, Intel i5-6400 @stock (dürfte in dem Test die meiste Zeit etwa 3,3 Ghz haben)
Code:
$ time echo "scale=100000; 24*atan(1/8)+8*atan(1/57)+4*atan(1/239)" | ./bc -l
....
7695262118097500640514975588965029300486760520801049153788541390942\
45316917199876289412772211294645682948602814931815602496778879498137\
77216229359437811004448060797672429276249510784153446429150842764520\
00204276947069804177583220909702029165734725158290463091035903784297\
75726517208772447409522671663060054697163879431711968734846887381866\
56751279298575016363411314627530499019135646823804329970695770150789\
337728658035712790913767420805655493624632

real    18m20,982s
user    18m18,005s
sys    0m1,739s
 
Inzwischen gibt es eine neuere Version von bc (5.2.1), aber sind nur kleinere Bugs, keine Geschwindigkeitsoptimierung.

Anderer Vergleichswert, ein R9-3900x unter Virtualbox auf Win10, Gast ist ubuntu 20.04.3 LTS x64.
Taktfrequenz im Test ca. 4,4 GHz.
Code:
$ time ./bc-pi-test.sh
3.141592653589793238462643383279502884197169399375105820974944592307\
...
77216229359437811004448060797672429276249510784153446429150842764520\
00204276947069804177583220909702029165734725158290463091035903784297\
75726517208772447409522671663060054697163879431711968734846887381866\
56751279298575016363411314627530499019135646823804329970695770150789\
337728658035712790913767420805655493624632

real    8m47.895s
user    14m40.371s
sys    0m1.134s

In der threadoptimierten Version, die aber eh nur drei Threads braucht.

edit:
Nicht in VM, sondern Live-Linux F36 ist der etwas schneller für die selbe Aufgabe
Code:
real     8m5.752s
user    13m36.785s
sys      0m1.732s

edit:
Hmpf., also da stimmt doch auch etwas nicht mit der Turbo-Taktfrequenz von 4,6 GHz, die zeitweise anliegen sollten, tun sie nämlich nicht.

edit:
Der Linux Kernel 5.18.19 verwendet nicht die schnellsten Kerne, das ist das Problem gewesen.
Wenn man nur Kerne 0,1, oder 6 oder 7 verwendet, dann takten die schon bis auf 4,6 GHz.
Habe mal ein xterm mit cpu-affinität aufgemacht, und dort den Benchmark gestartet:
Code:
taskset -c 0-1,12-13 xterm
und dort
Code:
$ time ./bc-pi-test.sh
...
77216229359437811004448060797672429276249510784153446429150842764520\
00204276947069804177583220909702029165734725158290463091035903784297\
75726517208772447409522671663060054697163879431711968734846887381866\
56751279298575016363411314627530499019135646823804329970695770150789\
337728658035712790913767420805655493624632

real    7m50,142s
user    13m6,281s
sys     0m1,910s
 
Zuletzt bearbeitet:
Auf Fedora36 mit R5-5500U, der eine ZEN2 CPU ist und bis 4GHz taktet, mit bc 5.3.3

Code:
$ time ./bc-pi-test.sh 
....
75726517208772447409522671663060054697163879431711968734846887381866\
56751279298575016363411314627530499019135646823804329970695770150789\
337728658035712790913767420805655493624632

real    8m53.322s
user    14m52.783s
sys     0m1.845s
 
Auf Fedora36 mit R7-5700G, der eine ZEN3 CPU ist und bis 4,6GHz taktet, mit bc 5.3.3

Code:
$ time ./bc-pi-test.sh 
....
75726517208772447409522671663060054697163879431711968734846887381866\
56751279298575016363411314627530499019135646823804329970695770150789\
337728658035712790913767420805655493624632

real    6m38,600s
user    11m2,200s
sys     0m1,416s
 
Amlogic S905x4 TV-Box mit 4x A55 Kerne @2GHz, unter CoreELEC:

Code:
$time ./bc-pi-test.sh > pi.txt

real    29m26.964s
user    50m44.716s
sys     0m10.160s

Das war ein bc von G.H. Ver. 6.2.2 statisch für ARM64 compiliert unter RaspiOS.
Im Vergleich zu weiter oben sieht man, dass ein Pi4B @2GHz doch etwas schneller ist (29 Minuten vs. 20 Minuten ca.).

edit:
von /tmp Verzeichnis (ramdisk) aus, und mit geschlossenem kodi

Der Pi4b @2GHz braucht mit selbem Binary nun 20m23,7s.
 
Zuletzt bearbeitet:
Zurück
Oben