Python und C++(C)

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Beim letzten [wiki=User_Group_Köln#BisherigeVortrge]Python-Treffen in Köln[/wiki] hatten wir den Vortrag Python in der Luft- und Raumfahrt.
Dort wird unterm Strich Python überall da eingesetzt wo es nicht auf nackte Rechenleistung ankommt. Für die eigentlichen Berechnungen/Simulationen kommt i.d.R. uralter Fortran Code oder C zum Einsatz. Python steuert/koordiniert das ganze dann... Auch langfristig wird das wohl so bleiben. In dem Falle liegt das aber nicht unbedingt an Python selber. Viel mehr sind die kosten für eine Neuentwicklung bestehender Rechenmodelle einfach zu groß.

Dennoch ist es schade das Python z.Z. nicht mit Dual-/Multi-Core Prozessoren zurecht kommt. Man bedenke nur das aktuelle Main-Stream Rechner schon mit Dualcores ausgestattet sind.
Ich weiß auch nicht wie es mit 64Bit Unterstützung ausschaut. Von wegen mehr als 2GB Speicher nutzten.

Hat da Python einen Trend verschlafen? Weiß jemand wie die Entwicklung in dieser Richtung aussieht?

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
BlackJack

Wieso kommt Python nicht mit Dualcore zurecht? Die Programme laufen auch dort.

Und um einen Vorteil von mehreren Prozessoren zu haben, muss man das Problem, das man lösen möchte, erst einmal parallelisieren. Falls das möglich ist. Auf jeden Fall ist das mit Arbeit verbunden.
Benutzeravatar
Dill
User
Beiträge: 470
Registriert: Mittwoch 10. Januar 2007, 14:52
Wohnort: Köln

wie ist das wenn mein python-programm multithreaded ist.
werden die threads nicht automatisch vom os auf die zur verfügung stehenden kerne verteilt?
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Klar läuft Python auf Dualcores, da hab ich mich falsch ausgedrückt. Aber so weit ich weiß, wirt auch mit multithreading nur immer ein core genutzt.

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
Dill
User
Beiträge: 470
Registriert: Mittwoch 10. Januar 2007, 14:52
Wohnort: Köln

http://www.parallelpython.com/

standardmässig laufen threads auf einem core.
liegt wohl daran, dass die ja irgendwie kommunizieren wollen und das ist nicht ohne weiteres möglich zwischen 2 cores.
habe jetzt auf anhieb aber nichts sinnvolles dazu gefunden, ausser dass das "obviously" nicht geht :)

tollerweise hat sich meine hochschule dazu entschieden alle vorlesungen zu parallelem rechnen und clustern abzuschaffen ... grade jetzt wo multicores für alle bezahlbar werden.
nervt mich dass ich davon kein plan hab.
BlackJack

Und wenn man das Problem auf mehrere Prozesse aufteilt, dann werden auch mit Python mehrere Kerne ausgenutzt. Es gibt den zusätzlichen Vorteil, dass man mehrere Prozesse, bei entsprechenden Kommunikationsmöglichkeiten, auch auf verschiedene Rechner verteilen kann. Das skaliert also viel besser nach oben.
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

BlackJack hat geschrieben:Wieso kommt Python nicht mit Dualcore zurecht? Die Programme laufen auch dort.

Und um einen Vorteil von mehreren Prozessoren zu haben, muss man das Problem, das man lösen möchte, erst einmal parallelisieren. Falls das möglich ist. Auf jeden Fall ist das mit Arbeit verbunden.
Nö. Hab hier eine AMD X2-3800 und Python nutzt nur einen Kern. Ob die Python 64bit Version SMT fähig ist weiß ich nicht, da ich hier nur Windows XP in der 32Bit Version habe.
jens hat geschrieben:Klar läuft Python auf Dualcores, da hab ich mich falsch ausgedrückt. Aber so weit ich weiß, wirt auch mit multithreading nur immer ein core genutzt.
Nein du hast dich schon richtige ausgedrückt (Finde ich zumindest). Das Python auf einen X-Core läuft ist ja klar, warum auch nciht. Aber der springende Punkt ist der, den du angesprochen hast -> Es wird immer nur ein Core genutzt.
BlackJack hat geschrieben:Und wenn man das Problem auf mehrere Prozesse aufteilt, dann werden auch mit Python mehrere Kerne ausgenutzt. Es gibt den zusätzlichen Vorteil, dass man mehrere Prozesse, bei entsprechenden Kommunikationsmöglichkeiten, auch auf verschiedene Rechner verteilen kann. Das skaliert also viel besser nach oben.
Und wie soll das gehen? Wenn ich in Python ein Programm schreibe, wie sage ich dann Python das er das ganze auf verschiedene Kerne verteile soll? Ist es den möglich in Pythons Threads zu erzeugen die man bestimmten Kernen zuweisen kann :?
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

sape hat geschrieben:
BlackJack hat geschrieben:Wieso kommt Python nicht mit Dualcore zurecht? Die Programme laufen auch dort.

Und um einen Vorteil von mehreren Prozessoren zu haben, muss man das Problem, das man lösen möchte, erst einmal parallelisieren. Falls das möglich ist. Auf jeden Fall ist das mit Arbeit verbunden.
Nö. Hab hier eine AMD X2-3800 und Python nutzt nur einen Kern. Ob die Python 64bit Version SMT fähig ist weiß ich nicht, da ich hier nur Windows XP in der 32Bit Version habe.
Wo wiederspricht das BlackJacks Aussage? Du bestätigst sie ja nur. Und nein, auch unter 64 Bit (IA64, x86_64, Alpha, UltraSPARC etc.) unterstützt Python kein SMP. Das liegt an der Architektur des Python-Interpreters.
sape hat geschrieben:
BlackJack hat geschrieben:Und wenn man das Problem auf mehrere Prozesse aufteilt, dann werden auch mit Python mehrere Kerne ausgenutzt. Es gibt den zusätzlichen Vorteil, dass man mehrere Prozesse, bei entsprechenden Kommunikationsmöglichkeiten, auch auf verschiedene Rechner verteilen kann. Das skaliert also viel besser nach oben.
Und wie soll das gehen? Wenn ich in Python ein Programm schreibe, wie sage ich dann Python das er das ganze auf verschiedene Kerne verteile soll? Ist es den möglich in Pythons Threads zu erzeugen die man bestimmten Kernen zuweisen kann :?
Sowas geht schlichtweg nicht. Alle Threads eines Python-Interpreters laufen auf einer CPU. Was man aber machen kann ist mehrere Interpreter auf verschiedenen CPUs zu starten und so zu kommunizieren.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
mq
User
Beiträge: 124
Registriert: Samstag 1. Januar 2005, 19:14

Wieso benutzt Python eigentlich keine nativen (=OS-Level) Threads?
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

Leonidas hat geschrieben: Wo wiederspricht das BlackJacks Aussage? Du bestätigst sie ja nur.
Stimmt, hast Recht. Ich hatte BlackJack falsch verstanden.
Leonidas hat geschrieben: Sowas geht schlichtweg nicht. Alle Threads eines Python-Interpreters laufen auf einer CPU. Was man aber machen kann ist mehrere Interpreter auf verschiedenen CPUs zu starten und so zu kommunizieren.
Keine schöne Lösung. Ist von GvR in dieser Hinsicht was geplant oder geht es generell nicht Python so zu entwerfen das es SMP fähig ist?
PmanX
User
Beiträge: 123
Registriert: Donnerstag 25. Januar 2007, 13:50
Wohnort: Germany.BB.LOS
Kontaktdaten:

Hallo,

was ich absolut nicht verstehen kann ist, dass so super allgemein drum herum geredet wird. Warum gibt es kein konkretes Projekt, wofür eine Lösung gesucht wird :!: Dann eine Weg suchen zu parallelisieren.
Was spricht dagegen, wenn ein Proz die Datenbank, ein weiterer den PVR .. bedient?
In den seltensten Fällen wird nur dieses eine Pythonprogramm laufen.

Gruß P.
Benutzeravatar
nkoehring
User
Beiträge: 543
Registriert: Mittwoch 7. Februar 2007, 17:37
Wohnort: naehe Halle/Saale
Kontaktdaten:

Mal zurueck zum Thema Geschwindigkeit... ich hab mir vor... - ja ich weiß garnichtmehr - ...ein oder zwei Wochen, mal eine kleine Schleife gebaut, die die letzte Primzahl vor einer Gegebenen Zahl sucht.

Also zB gibst du die 10000 an und bekommst dann 9973 zurueck.

Und als ich hier im Thread stoeberte kam mir mal die Idee, einen Vergleich zu ziehen... die Schleife normal und mit Psyco:

(gezeigt wird immer die Ausgabe der dritten Ausfuehrung)

Code: Alles auswählen

psy@BrAIN1ak> ./letzte_primzahl.py 100000
99991 ( 0.0576159954071 secs)
psy@BrAIN1ak> ./letzte_primzahl.py 1000000
999983 ( 0.548065900803 secs)
psy@BrAIN1ak> ./letzte_primzahl.py 10000000
9999991 ( 5.59474992752 secs)
und jetzt... *trommelwirbel* 8)

Code: Alles auswählen

psy@BrAIN1ak> ./letzte_primzahl_psyco.py 100000
99991 ( 0.00420188903809 secs)
psy@BrAIN1ak> ./letzte_primzahl_psyco.py 1000000
999983 ( 0.0389289855957 secs)
psy@BrAIN1ak> ./letzte_primzahl_psyco.py 10000000
9999991 ( 0.379332065582 secs)

...ja nun bin ich wirklich sprachlos :o
Vorallem weil dieser Geschwindigkeitszuwachs durch zwei Zeilen Code entsteht. Hier der Code, fuer interessierte:

Code: Alles auswählen

#!/usr/bin/python

from sys import argv
from time import time

import psyco
psyco.full()

stop = int(argv[1])

def quer(x):
    x = [int(n) for n in list(str(x))]
    return sum(x)


def is_prim(x):
    if str(x).endswith("5"): return False
    elif int(str(x)[-1])%2 == 0: return False
    elif x>10:
        if quer(x)%3 == 0: return False

    n = 2
    while n<x:
        if x%n == 0: break
        else: n+=1
    else:
        return True
    return False

stamp = time()
while not is_prim(stop): stop -= 1
stamp=time()-stamp
print stop, '(', stamp, 'secs)'
natuerlich koennte man noch abfangen, ob Psyco ueberhaupt installiert ist usw... aber naja... es ist ja nur fuer mich, eigentlich ;)
[url=http://www.python-forum.de/post-86552.html]~ Wahnsinn ist auch nur eine andere Form der Intelligenz ~[/url]
hackerkey://v4sw6CYUShw5pr7Uck3ma3/4u7LNw2/3TXGm5l6+GSOarch/i2e6+t2b9GOen7g5RAPa2XsMr2
BlackJack

@lumax: Python benutzt die Threads vom Betriebssystem.

Ich weiss nicht ob sich das jeder der Diskutanten klar macht: Ein Programm kann nicht auf magische Weise mehrere Prozessoren/Kerne benutzen. Da muss der Programmierer immer etwas für tun. Wenn das "global interpreter lock" nicht mehr vorhanden wäre, ändert sich an allen Programmen, die keine Threads benutzen rein gar nichts.

Selbst wenn es möglich wäre, dass Python-Bytecode in mehreren Threads parallel ausgeführt wird, ist immer noch nicht garantiert, dass diese Threads auch auf mehrere Prozessoren/Kerne verteilt werden.
Benutzeravatar
nkoehring
User
Beiträge: 543
Registriert: Mittwoch 7. Februar 2007, 17:37
Wohnort: naehe Halle/Saale
Kontaktdaten:

Einfach um meinen Kopf ein wenig frei zu kriegen, nach tagelanger Programmierung an einer Sache... habe ich die Primzahlenschleife mal in C implementiert. Hier das Ergebniss:

Code: Alles auswählen

psy@BrAIN1ak> ./a.out
99991 (0 clockcycles)  # <1 secs
999983 (30000 clockcycles)  # 0.03 secs
9999991 (270000 clockcycles) # 0.27 secs
Eine Millionen Clockcycles entsprechen hier einer Sekunde. Ich hoffe das diese Art der Messung hier passt.


Und hier wieder der Code fuer Interessierte...

Code: Alles auswählen

/*
 * Gibt die letzte Primzahl vor der per Argument uebergebenen Zahl aus.
 */


#include <stdio.h>
#include <time.h>


int quer(int x)
{
    int wertigkeit, hilf, summe = 0;

    hilf=x;
    wertigkeit = 1;

    while((hilf=hilf/10) != 0) wertigkeit=wertigkeit * 10;

    do {
        summe = summe + x / wertigkeit;
        x = x % wertigkeit;
        wertigkeit = wertigkeit / 10;

    } while(wertigkeit > 0);

    return summe;
}

int is_prim(int x)
{
    int n = 2;

    if (x%5 == 0) return 0;
    if (x%2 == 0) return 0;
    if (x>10) {
        if (quer(x)%3 == 0) return 0;
    }
    
    while (n<x) {
        if (x%n == 0) return 0;
        else n++;
    }
    return 1;
}


int main()
{
    int stop;
    clock_t stamp;

    stop = 100000;
    stamp = clock();
    while (!is_prim(stop)) stop--;
    stamp = clock() - stamp;
    printf("%d (%d clockcycles)\n", stop, stamp);

    stop = 1000000;
    stamp = clock();
    while (!is_prim(stop)) stop--;
    stamp = clock() - stamp;
    printf("%d (%d clockcycles)\n", stop, stamp);

    stop = 10000000;
    stamp = clock();
    while (!is_prim(stop)) stop--;
    stamp = clock() - stamp;
    printf("%d (%d clockcycles)\n", stop, stamp);

    return 0;
}
:oops: ist der lang :shock:
[url=http://www.python-forum.de/post-86552.html]~ Wahnsinn ist auch nur eine andere Form der Intelligenz ~[/url]
hackerkey://v4sw6CYUShw5pr7Uck3ma3/4u7LNw2/3TXGm5l6+GSOarch/i2e6+t2b9GOen7g5RAPa2XsMr2
BlackJack

Das mit der Quersumme hatte irgendwie bei mir gar keinen Einfluss auf die Laufzeit. Ich hab's mal ein wenig verändert. Ist jetzt kürzer und schneller:

Code: Alles auswählen

$ ./a.out
99991 (0 clockcycles)
999983 (0 clockcycles)
9999991 (0 clockcycles)
Und der Code:

Code: Alles auswählen

#include <math.h>
#include <stdio.h>
#include <time.h>


int is_prim(int x)
{
    int n;

    if (x == 2) return 1;
    if (!(x & 1)) return 0;
    for (n = 3; n < sqrt(x); n += 2) {
        if (!(x % n)) return 0;
    }
    return 1;
}


int main()
{
    int i, stop;
    clock_t stamp;

    for (i = 0; i < 3; ++i) {
        stop = 100000 * pow(10, i);
        stamp = clock();
        while (!is_prim(stop)) stop--;
        stamp = clock() - stamp;
        printf("%d (%d clockcycles)\n", stop, (int) stamp);
    }

    return 0;
}
Benutzeravatar
nkoehring
User
Beiträge: 543
Registriert: Mittwoch 7. Februar 2007, 17:37
Wohnort: naehe Halle/Saale
Kontaktdaten:

okay.. du beherrscht C eindeutig besser als ich ^^
Ich hab allerdings auch direkt die Python-Implementierung "abgeschrieben" ...ich wollte ja nun einen Vergleich ziehen.

Aber danke dafuer... :D

EDIT: Das klappt nicht... irgendwie findet er sqrt() und pow() nicht -.-

EDIT2: Also wenn ich das hier mache:

Code: Alles auswählen

#include <stdio.h>
#include <math.h>


int main(int argc, char *argv)
{
        printf("> %f <\n", sqrt(pow(5, 2)));

        return 0;
}
...klappts... vielleicht bin ich auch zu bloed... denn bei meinem kumpel (DevC++ unter WinXP vermute ich mal) klappt dein Code auch. Ich hab uebrigens den GCC4.x unter nem normalen x86er Linuxkernel...

EDIT3 ^^ GCC4.1.1 und GCC3.4.6 habe ich jetzt getestet
[url=http://www.python-forum.de/post-86552.html]~ Wahnsinn ist auch nur eine andere Form der Intelligenz ~[/url]
hackerkey://v4sw6CYUShw5pr7Uck3ma3/4u7LNw2/3TXGm5l6+GSOarch/i2e6+t2b9GOen7g5RAPa2XsMr2
Benutzeravatar
nkoehring
User
Beiträge: 543
Registriert: Mittwoch 7. Februar 2007, 17:37
Wohnort: naehe Halle/Saale
Kontaktdaten:

wow... also egal wieso die C-Variante nicht funktionieren will... in Python (mit Psyco) ist es so dermaßen schnell, was du da gebaut hast ^^... ja ist auch klar. Du erhoehst n gleich um 2 (sinnigerweise ^^) und ueberpruefst nur bis zur Wurzel der gegebenen Zahl.

Naja.. die Python-Implementation ist jedenfalls so schnell, dass ich die letzte Primzahl unter einer Billion in 0.6 sekunden ausrechne... meine alte Variante rechnet immernoch... keine Ahnung wie lang. Ein paar Minuten sinds aber schon. :roll:

Wer die neue Pythonvariante haben mag:

Code: Alles auswählen

#!/usr/bin/python

from sys import argv
from time import time

import psyco
psyco.full()

stop = int(argv[1])

def is_prim(x):
    if x==2: return True
    if not (x & 1): return False

    n = 3
    while n < (x**0.5):
        if not x%n: return False
        n += 2

    return True

stamp = time()
while not is_prim(stop): stop -= 1
stamp=time()-stamp
print stop, '(', stamp, 'secs)'
[url=http://www.python-forum.de/post-86552.html]~ Wahnsinn ist auch nur eine andere Form der Intelligenz ~[/url]
hackerkey://v4sw6CYUShw5pr7Uck3ma3/4u7LNw2/3TXGm5l6+GSOarch/i2e6+t2b9GOen7g5RAPa2XsMr2
BlackJack

Falls sich der Linker beschwert:

Code: Alles auswählen

$ gcc -O3 -Wall -ansi -pedantic test.c
/tmp/ccGLyIIq.o: In function `is_prim':test.c:(.text+0x47): undefined reference to `sqrt'
/tmp/ccGLyIIq.o: In function `main':test.c:(.text+0xcd): undefined reference to `pow'
:test.c:(.text+0x1a1): undefined reference to `sqrt'
collect2: ld returned 1 exit status
Dann hast Du nicht gesagt, dass die Mathebibliothek mit eingebunden werden soll:

Code: Alles auswählen

$ gcc -O3 -Wall -ansi -pedantic -lm test.c
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

BlackJack hat geschrieben:Ich weiss nicht ob sich das jeder der Diskutanten klar macht: Ein Programm kann nicht auf magische Weise mehrere Prozessoren/Kerne benutzen. Da muss der Programmierer immer etwas für tun.
Da hast du wohl recht... Allerdings ist es IMHO z.Z. so, das ein Programmiere keine Möglichkeiten hat sein Programm zu parallelisieren. Der einzige Weg ist es wohl ein Python Interpreter pro Prozessor/Core zu starten.

Ich meine, ich selber werde wohl nie etwas in der Richtung machen. Ich frage mich halt aber dennoch, ob Python da nicht ein Trend verschlafen hat. Das wäre wirklich schade.
Ich meine Python wird halt recht oft, im Forschungumfeld eingesetzt. Dort ist das Thema Parallelisierung schon wichtig, denke ich. Dort könnte es vielleicht auch wichtig sein, mehr als 2GB Speicher zu benutzten, was IMHO auch nur gescheit mit 64Bit geht. Wie sieht es damit aus?

Weiß jemand eigentlich was andere Programmiersprachen in der Richtung so bieten?

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
BlackJack

Im Forschungsumfeld wird AFAIK fast immer auf Prozesse gesetzt. Das skaliert einfach besser, weil man die Berechnungen auch auf verschiedene Rechner verteilen kann. Meistens wird wohl MPI als Schnittstelle zur Kommunikation eingesetzt.

Und das man keine Möglichkeiten in Python hat, hast Du im gleichen Satz ja widerlegt: Prozesse. Mit relativ einfach zu programmierender Kommunikation beispielsweise über XML-RPC oder Pyro.

Und das GIL betrifft auch nur Python-Bytecode, dass heisst in C-Erweiterungen kann man das durchaus umgehen.
Antworten