Portal > Foren > Java > Allgemeine Java-Programmierung > Producer/Consumer vs. produce and consume
Antwort
 
LinkBack Themen-Optionen Thema durchsuchen
Alt 07.02.2010, 12:27 Nach oben    #1
Erfahrener Benutzer
 
Registriert seit: 16.08.2008
Ort: Mecklenburg-Vorpommern
Beiträge: 314
Standard Producer/Consumer vs. produce and consume

Hallo Javanesen ,

Multithreading ist ja ein schöner Bestandteil von Java. Da gibt's tolle Stichworte wie "Parallelität", was soviel bedeutet wie "vermeide soviel sequenzielle Arbeit, wie nur möglich" und vieles mehr.

Ich stehe im Moment vor einer Designfrage für eine Main-Methode.

Ein bisschen was zur Problematik:
Ich muss Daten aus einer Datenbank entnehmen.
Diese Daten werden portioniert aus der Datenbank geholt (z.B. immer 1.000 Datensätze) und anschließend in einem eigenen Objekt verarbeitet und sollen danach in eine andere Tabelle der Datenbank geschrieben werden.

Designüberlegungen:
a) Ich habe einen oder mehrere Producer und einen oder mehrere Consumer. Die Producer holen die Daten aus der Datenbank, die Consumer nehmen sich die Daten der Producer, verarbeiten sie und schreiben sie in die neue Datenbanktabelle.
Was dagegen spricht: Wieso sollte ich dann nicht gleich die Producer einsparen und stattdessen jeden Thread selbstständig die Daten aus der DB abholen und verarbeiten lassen?

b) Ich habe einen Producer und viele Consumer. Der Producer hält ResultSets vor, die die Consumer abholen können. Problem: Was ist, wenn viele Consumer zeitgleich fertig werden und auf einen Producer warten müssen, der erst Daten abholen muss?

c) Nach Überarbeitung des Datenbankmodelles, kann man für c) etwas anders vorgehen. Ich habe einen DataProducer, dieser holt die Daten aus der Datenbank. Als nächstes kommt ein SortingProducer dazu. Die Daten stehen über einen bestimmten mehrdeutigen Schlüssel miteinander in Verbindung. Es kann sein, dass Durch eine LIMIT-Klausel, die paketweise die Daten ausliest, Werte mit zwei identischen Schlüsseln in zwei verschiedenen Paketen vorhanden sind. Der SortingProducer sieht sich das Ende des vorletzten Paketes an und vergleicht es mit dem Beginn des letzten Paketes. Falls die Schlüssel identisch sind, passt er die ResultSets an.
Die ResultSets werden dann an Consumer übergeben. Diese verarbeiten die Daten und schreiben sie in die neue Tabelle.
Im Falle von a) und b) würden die Producer die Arbeit der Data- und SortingProducer aus c) übernehmen.

Welchen Ansatz haltet ihr für den besten?

EDIT: Das DB-Design konnte ich überarbeiten. Das Ganze ist jetzt mit einem Join möglich.

Vielen Dank!

Geändert von Sekundentakt (07.02.2010 um 16:14 Uhr)
Sekundentakt ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 08.02.2010, 07:37 Nach oben    #2
fka Gottzilla
 
Benutzerbild von The_S
 
Registriert seit: 02.02.2005
Ort: Würzburg
Beiträge: 753
Standard

Zitat:
Zitat von Sekundentakt Beitrag anzeigen
Ich stehe im Moment vor einer Designfrage für eine Main-Methode.
Ui ... Design einer Main-Methode ... . Grundsätzlich sollte es gar nicht erst soweit kommen, dass man eine (Main)-Methode designen muss ;) .

Zitat:
Zitat von Sekundentakt Beitrag anzeigen
EDIT: Das DB-Design konnte ich überarbeiten. Das Ganze ist jetzt mit einem Join möglich.

Vielen Dank!
Heißt das jetzt, dass das ganze Problem gelöst ist?
The_S ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 09.02.2010, 21:35 Nach oben    #3
Erfahrener Benutzer
 
Registriert seit: 16.08.2008
Ort: Mecklenburg-Vorpommern
Beiträge: 314
Standard

Zitat:
Heißt das jetzt, dass das ganze Problem gelöst ist?
Nein ;). Das "Vielen Dank" an dieser Stelle bezog sich eher auf die Mühe des Nachvollziehens und Helfens :).

Zitat:
Ui ... Design einer Main-Methode ... . Grundsätzlich sollte es gar nicht erst soweit kommen, dass man eine (Main)-Methode designen muss .
Okay, etwas unklar ausgedrückt, stimmt.

Grundsätzlich gings mir aber um das Design der Producer-Threads und Consumer-Threads, um einen möglichst hohen Datendurchsatz zu erreichen.

Ich hoffe, dass das Problem jetzt etwas klarer ist.
Sekundentakt ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 10.02.2010, 07:26 Nach oben    #4
fka Gottzilla
 
Benutzerbild von The_S
 
Registriert seit: 02.02.2005
Ort: Würzburg
Beiträge: 753
Standard

Generell wäre es natürlich am schönsten, wenn du alles in einem SQL unterbringen könntest - Auslesen, Aufbereitung und Einfügen. Je nach Komplexität der Aufbereitung wäre das natürlich nicht gerade trivial.

Mehrere Producer, wie du sie nennst, machen eher weniger Sinn. Du hast trotzdem nur eine Datenbank im Hintergrund laufen, die auch nicht schneller fertig wird, wenn 50 Threads darauf zugreifen.

Mehrere Consumer macht nur dann Sinn, wenn du einen entsprechenden Multicore-Prozessor hast, und die Verarbeitung der Daten deutlich mehr Zeit in Anspruch nimmt, als das Auslesen.

Generell könntest du noch eine weitere "Schicht" (das Wort passt hier zwar nicht 100prozentig, aber ich denke du weißt, was gemeint ist) einführen. Und zwar die, die die Daten wieder in die DB schreibt => Leser, Verarbeiter, Schreiber. Ich seh jetzt nicht so den Sinn, warum der Aufbereiter die Daten auch wieder schreiben sollte, wenn es auch einen separaten Leser gibt.
The_S ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 13.02.2010, 15:29 Nach oben    #5
Erfahrener Benutzer
 
Registriert seit: 16.08.2008
Ort: Mecklenburg-Vorpommern
Beiträge: 314
Standard

So, die Woche über war ich nicht erreichbar :).

Klar, das in drei Teilprozesse aufzugliedern macht an dieser Stelle schon Sinn. :)

Zur Datenbank: Ich nahm immer an, dass seitens der DB für jeden Lesezugriff ein einzelner Thread bei Bedarf gestartet wird. Bist Du dir da sicher, dass die das wirklich sequenziell abarbeiten???
Sekundentakt ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 14.02.2010, 11:27 Nach oben    #6
fka Gottzilla
 
Benutzerbild von The_S
 
Registriert seit: 02.02.2005
Ort: Würzburg
Beiträge: 753
Standard

Kommt natürlich auf die Datenbank und ggf. die Konfiguration an. Und da du auch nicht schreibend darauf zugreifst, sollten die Tabellen auch nicht gesperrt werden.

Aber wenn die DB mit einer Abfrage beschäftigt ist, dann wird sie mit der Abfrage nicht schneller fertig, wenn noch ein, zwei oder drei weitere Abfragen reinkommen. Stattdessen wird sie eher länger pro Abfrage benötigen.

Kannste dir ganz leicht an nem Beispiel klar machen. Wenn du gleichzeitig ein Java-Programm für einen Kunden und die Hausaufgaben für die Schule machen musst, dann bist du zwar prinzipiell in der Lage beides gleichzeitig zu machen (wenn auch viel ineffektiver als ein Computer), aber im Endeffekt (wenn du so effizient wie ein Computer wärst) würdest du genau so lange für beides benötigen, wenn du das nacheinander gemacht hättest.

Anders schaut es natürlich aus, wenn du Hausaufgaben machen musst, Kaffee kochen und 2000 Seiten kopieren. Du stellst vermutlich als erstes den Kopierer ein, der dann die Arbeit von alleine macht, als nächstes die Kaffeemaschine, die die Arbeit dann auch von alleine macht, und kümmerst dich dann um die Hausaufgaben. Ist vermutlich sehr viel schneller, als wenn du wartest, bis der Kopierer fertig ist, dann den Kaffee kochst, wartest bis die Maschine fertig ist, und dann mit deinen Hausaufgaben beginnst ;) .

Wenn du also ein Single-Core System hast, nutzen dir Threads nur etwas, wenn die jeweiligen Arbeiten unterschiedliche Ressourcen beanspruchen. Alle Primzahlen in einem bestimmten Bereich zu bestimmen geht nicht schneller, wenn du den Bereich in zwei Bereiche unterteilst, die du dann parallel berechnen lässt (beansprucht ja beides ausschließlich CPU). Es macht jedoch durchaus Sinn, einen großen Festplattenzugriff, eine Anfrage an einen Server und eine komplexe Berechnung in jeweils einen Thread auszulagern, da alle drei Aufgaben unterschiedliche Ressourcen beanspruchen würden.

Anders sieht es bei einem Mulitcore-System aus. Da hier wirklich mehrere physikalisch getrennte Recheneinheiten vorhanden sind, macht es hier auch Sinn, die Primzahlen getrennt voneinander zu berechnen. Vergleichbar damit, dass du einen Kollegen neben dir stehen hast, der für dich die Hausaufgaben macht, während du dich um das Java Programm kümmerst.

Zugriffe von mehreren Threads auf eine DB macht also nur dann Sinn, wenn die Datenbank auch auf einem Multicore-System läuft. Und selbst dann ist es fraglich, ob mehrere Threads wirklich sinnvoll sind. Aber das kommt wieder auf die Arbeitsweise der DB an.
The_S ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 14.02.2010, 19:11 Nach oben    #7
Erfahrener Benutzer
 
Registriert seit: 16.08.2008
Ort: Mecklenburg-Vorpommern
Beiträge: 314
Standard

Prinzipiell erzählst Du mir da nichts Neues ;).

Wenn Du aber weißt, dass Du portioniert immer ungefähr 1.000 Datensätze aus einer DB lesen sollst, würde es schon Sinn machen, wenn Du mehrere Leute an verschiedene Stellen setzt.

Du weißt, Deine IDs sind nummerisch und unique, also kannst Du portioniert Daten abfragen. Klar, vielleicht gibt es den Datensatz mit der ID 2.000 nicht mehr, aber dann kannst Du nachsehen, ob es eine 1.999 gibt. Das Paket ist dann zwar kleiner, aber du kannst es trotzdem verteilt abfragen.

Alternativ könnte man jetzt auf die Idee kommen mit der LIMIT-Klausel zu arbeiten. Jeder, der glaubt, dass er einen Leser auf Datensatz 1 und einen anderen Leser auf Datensatz 50.000 setzen kann, sollte das mal versuchen und feststellen, dass es einen marginalen oder nichtvorhandenen Geschwindigkeitsvorteil gibt. Anders natürlich, wenn man das über IDs macht.

Ansonsten hast Du Recht. :)

Leider wird immer noch häufig versucht, Multithreading mit Single-Core-Abläufen zu erklären, was im Zeitalter der Mehrkernprozessoren irreführend ist. Sobald man mehrere Prozessoren hat, wird tatsächlich parallel gearbeitet, sofern man denn entsprechend parallelisierbare Anwendungen schreibt.
Sekundentakt ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 15.02.2010, 07:29 Nach oben    #8
fka Gottzilla
 
Benutzerbild von The_S
 
Registriert seit: 02.02.2005
Ort: Würzburg
Beiträge: 753
Standard

Zitat:
Zitat von Sekundentakt Beitrag anzeigen
Wenn Du aber weißt, dass Du portioniert immer ungefähr 1.000 Datensätze aus einer DB lesen sollst, würde es schon Sinn machen, wenn Du mehrere Leute an verschiedene Stellen setzt.

Du weißt, Deine IDs sind nummerisch und unique, also kannst Du portioniert Daten abfragen. Klar, vielleicht gibt es den Datensatz mit der ID 2.000 nicht mehr, aber dann kannst Du nachsehen, ob es eine 1.999 gibt. Das Paket ist dann zwar kleiner, aber du kannst es trotzdem verteilt abfragen.
Der Zusammenhang mit meiner Antwort und deiner ursprünglichen Frage ist mir jetzt noch nicht so ganz klar.

Zitat:
Zitat von Sekundentakt Beitrag anzeigen
Alternativ könnte man jetzt auf die Idee kommen mit der LIMIT-Klausel zu arbeiten. Jeder, der glaubt, dass er einen Leser auf Datensatz 1 und einen anderen Leser auf Datensatz 50.000 setzen kann, sollte das mal versuchen und feststellen, dass es einen marginalen oder nichtvorhandenen Geschwindigkeitsvorteil gibt. Anders natürlich, wenn man das über IDs macht.
Auch hier fehlt mir irgendwie der Context.

Um es noch einmal zusammen zu fassen: Du fragtest, ob parallele Zugriffe auf eine DB Sinn machen. Ich antwortete, dass es darauf ankommt, ob die DB auf einem Multicore-System liegt und ob die DB dieses auch ausnutzt/ausnutzen kann. Es heißt ja nicht, dass die DB auch mehrere Threads eröffnet, nur weil du parallel anfragst. Außerdem nutzen dir mehrere CPUs wenig, wenn die meiste Zeit damit verbracht wird, die Daten aus dem Arbeitsspeicher, Cache oder gar von der Festplatte zu lesen.

Zumindest weiß ich jetzt schon einmal, dass du vermutlich eine MySQL DB verwendest (Deine letzten Threads + LIMIT-Befehl ;) ), was mir aber nicht weiterhilft, da ich nicht weiß, wie MySQL mit den von mir angeführten Kritikpunkten umgeht. Solltest du vielleicht mal in Erfahrung bringen :) .

Zitat:
Zitat von Sekundentakt Beitrag anzeigen
Ansonsten hast Du Recht. :)
Da ich nach wie vor keine Ahnung habe, wie sich deine Aussagen auf meine Antworen beziehen, gehe ich einfach mal davon aus, dass ich in allen Punkten recht habe .

Zitat:
Zitat von Sekundentakt Beitrag anzeigen
Leider wird immer noch häufig versucht, Multithreading mit Single-Core-Abläufen zu erklären, was im Zeitalter der Mehrkernprozessoren irreführend ist. Sobald man mehrere Prozessoren hat, wird tatsächlich parallel gearbeitet, sofern man denn entsprechend parallelisierbare Anwendungen schreibt.
Nochmal: Das gilt nur, wenn auch wirklich von allen Threads die CPU belastet wird. Ein Multicore nutzt dir gar nichts, wenn du 2TB von der Festplatte einlesen musst :-P . Von daher finde ich eine Erklärung anhand von Single-Core-Abläufen nicht verkehrt, weil einem so klar wird, dass eben nicht immer Multithreading sinnvoll ist. Zudem ein Thread auch auf einem Multicore-System nicht "kostenlos" ist, und die Anzahl der Threads auch durch die Anzahl der Kerne beschränkt ist.
The_S ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 15.02.2010, 10:43 Nach oben    #9
Erfahrener Benutzer
 
Registriert seit: 16.08.2008
Ort: Mecklenburg-Vorpommern
Beiträge: 314
Standard

Zitat:
Der Zusammenhang mit meiner Antwort und deiner ursprünglichen Frage ist mir jetzt noch nicht so ganz klar.
Nunja, ich hole Daten portioniert aus einer Datenbank. Jede Portion hat eine Größe von ca. 1.000 Datensätzen.

Gesetz dem Fall die Daten liegen nicht auf Platte, sondern in einer Memory-Table, dann macht es durchaus Sinn bei 4mio Datensätzen einen Producer an den Anfang der Tabelle zu setzen und von dort aus portioniert Daten aus der Tabelle zu holen und einen Producer in die ungefähre Mitte der Tabelle zu schicken und selbiges dort zu tun.
Du kannst dann z.B. sagen "selektiere alle Datensätze mit einer ID größer als x LIMIT 0, 1000", wobei x die ID des tausendsten bzw. letzten Datensatzes der letzten Ergebnismenge ist.
Soweit ich weiß kann man nämlich auf den Arbeitsspeicher frei zugreifen, anders als bei einer Festplatte.
Insofern nutze ich zwar nicht unbedingt die Eigenschaften eines Multicores aus, das ist richtig, aber sinnvoll wäre es in diesem Falle schon.

Zitat:
was mir aber nicht weiterhilft, da ich nicht weiß, wie MySQL mit den von mir angeführten Kritikpunkten umgeht. Solltest du vielleicht mal in Erfahrung bringen .
Ich meine mal irgendwo gelesen zu haben, dass MySQL - solange die Tabelle nicht gelockt wird - paralleles Lesen zulässt, sofern die Hardware mitspielt. Vielleicht finde ich dazu noch einen Artikel.

Zur LIMIT-Klausel:
Zwei Beispiele:
LIMIT 0, 1000 -> zeigt Dir die ersten 1.000 Ergebnisse deiner Abfrage an.
LIMIT 100, 1000 -> überspringt die ersten 100 Ergebnisse und zeigt dann die darauf folgenden 1.000 Ergebnisse an.

Wenn ich jetzt sage LIMIT 50000, 1000 überspringt er die ersten 50.000 Ergebnisse und zeigt mir die darauf folgenden 1.000 an. Das bringt mir aber kaum Geschwindigkeitsvorteile, weil die ersten 50.000 Ergebnisse trotzdem berechnet werden müssen und nur nicht zurückgegeben werden.
Anders wäre es, wenn ich die ID nehme und sowas mache wie
SELECT spalte FROM tabelle WHERE ID > 1 LIMIT 0, 1000 oder
SELECT spalte FROM tabelle WHERE ID > 50000 LIMIT 0,1000
Hier nutze ich den Index aus, was mir tatsächlich Geschwindigkeitsvorteile bietet.
Sekundentakt ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 15.02.2010, 13:22 Nach oben    #10
fka Gottzilla
 
Benutzerbild von The_S
 
Registriert seit: 02.02.2005
Ort: Würzburg
Beiträge: 753
Standard

Ich glaub so wird das nichts .

Zitat:
Zitat von Sekundentakt Beitrag anzeigen
Nunja, ich hole Daten portioniert aus einer Datenbank. Jede Portion hat eine Größe von ca. 1.000 Datensätzen.

Gesetz dem Fall die Daten liegen nicht auf Platte, sondern in einer Memory-Table, dann macht es durchaus Sinn bei 4mio Datensätzen einen Producer an den Anfang der Tabelle zu setzen und von dort aus portioniert Daten aus der Tabelle zu holen und einen Producer in die ungefähre Mitte der Tabelle zu schicken und selbiges dort zu tun.
Du kannst dann z.B. sagen "selektiere alle Datensätze mit einer ID größer als x LIMIT 0, 1000", wobei x die ID des tausendsten bzw. letzten Datensatzes der letzten Ergebnismenge ist.
Soweit ich weiß kann man nämlich auf den Arbeitsspeicher frei zugreifen, anders als bei einer Festplatte.
Insofern nutze ich zwar nicht unbedingt die Eigenschaften eines Multicores aus, das ist richtig, aber sinnvoll wäre es in diesem Falle schon.

Zur LIMIT-Klausel:
Zwei Beispiele:
LIMIT 0, 1000 -> zeigt Dir die ersten 1.000 Ergebnisse deiner Abfrage an.
LIMIT 100, 1000 -> überspringt die ersten 100 Ergebnisse und zeigt dann die darauf folgenden 1.000 Ergebnisse an.

Wenn ich jetzt sage LIMIT 50000, 1000 überspringt er die ersten 50.000 Ergebnisse und zeigt mir die darauf folgenden 1.000 an. Das bringt mir aber kaum Geschwindigkeitsvorteile, weil die ersten 50.000 Ergebnisse trotzdem berechnet werden müssen und nur nicht zurückgegeben werden.
Anders wäre es, wenn ich die ID nehme und sowas mache wie
SELECT spalte FROM tabelle WHERE ID > 1 LIMIT 0, 1000 oder
SELECT spalte FROM tabelle WHERE ID > 50000 LIMIT 0,1000
Hier nutze ich den Index aus, was mir tatsächlich Geschwindigkeitsvorteile bietet.
Das alles hat mich bei deinem letzten Post schon nicht interessiert und tut es jetzt auch nicht. Ich weiß auch nicht, wie das dir bei deinem Problem weiterhelfen soll. Das einzig Interessante ist diese Stelle hier:

Zitat:
Zitat von Sekundentakt Beitrag anzeigen
Zitat:
was mir aber nicht weiterhilft, da ich nicht weiß, wie MySQL mit den von mir angeführten Kritikpunkten umgeht. Solltest du vielleicht mal in Erfahrung bringen .
Ich meine mal irgendwo gelesen zu haben, dass MySQL - solange die Tabelle nicht gelockt wird - paralleles Lesen zulässt, sofern die Hardware mitspielt. Vielleicht finde ich dazu noch einen Artikel.
Klär das ab, und wenn MySQL sich so verhält, wie du gerne hättest: Wunderbar, dann mach separate Threads. Ansonsten lass es sein ;) . Alles andere kann man im Anschluss klären.

Du kannst ja auch einfach deinen Code einmal mit und einmal ohne Threads durchlaufen lassen und die Ergebnisse vergleichen. Aber Achtung: Viele Datenbanken cachen Anfragen bzw. spielt der Java JIT Compiler auch eine Rolle bei Mikrobenchmarks.
The_S ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 15.02.2010, 14:37 Nach oben    #11
Sesselkleber
 
Benutzerbild von sparrow
 
Registriert seit: 17.01.2005
Beiträge: 626
Standard

Zitat:
Zitat von Sekundentakt Beitrag anzeigen
Soweit ich weiß kann man nämlich auf den Arbeitsspeicher frei zugreifen, anders als bei einer Festplatte.
Nö.
Mehr hier: Speicherzugriff ? Wikipedia

Und deine Datenbank wird doch sicher nicht auf einem Magnetband liegen.

Gruß
Sparrow
sparrow ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 15.02.2010, 15:06 Nach oben    #12
Erfahrener Benutzer
 
Registriert seit: 16.08.2008
Ort: Mecklenburg-Vorpommern
Beiträge: 314
Standard

Zitat:
Klär das ab, und wenn MySQL sich so verhält, wie du gerne hättest: Wunderbar, dann mach separate Threads. Ansonsten lass es sein . Alles andere kann man im Anschluss klären.
Ich finde den Artikel leider nicht mehr. Vielleicht ging es auch um ein mögliches Entwicklungsszenario. Gut, bis ich eine Referenz gefunden habe, die meine obige Behauptung untermauert, muss ich Dir Recht geben: Das Ganze wird sequenziell abgearbeitet. :)

Zitat:
Nö.
Zitat:
Der Speicherzugriff wird durch ein Programm veranlasst, das die Adresse eines bestimmten Speicherinhaltes kennt. Um den Zugriff auf die betreffende Speicherzelle zu veranlassen, wird zunächst die Adresse in das Speicheradressregister des Prozessors geladen. Dies bewirkt, dass die Adresse auch auf dem Adressbus angelegt wird. Wenn der Prozessor nun seinen lesenden Zugriff auf den Arbeitsspeicher ausführt, wird durch die auf dem Adressbus vorgegebene Adresse die richtige Speicherzelle ausgelesen und ihr Inhalt über den Datenbus in das Speicherinhaltsregister des Prozessors übertragen.
Man müsste jetzt nur herausfinden, ob so ein Adressbus parallel mehrere Prozessorkerne ansteuern kann, oder nicht.

Bei der Festplatte hängt die Lesegeschwindigkeit von den Umdrehungen der Platte ab, der Zugriff auf den Arbeitsspeicher ist dagegen frei ansteuerbar.
RAM
Sekundentakt ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 15.02.2010, 16:50 Nach oben    #13
Sesselkleber
 
Benutzerbild von sparrow
 
Registriert seit: 17.01.2005
Beiträge: 626
Standard

Zitat:
Zitat von Sekundentakt Beitrag anzeigen
Bei der Festplatte hängt die Lesegeschwindigkeit von den Umdrehungen der Platte ab, der Zugriff auf den Arbeitsspeicher ist dagegen frei ansteuerbar.
RAM
Du verwurschelst hier einige Dinge die so nicht zusammen gehören.
Sowohl bei Fesplatten als auch beim RAM handelt es sich um wahlfreien Speicher. Im Groben: du kannst eine bestimmte Adresse direkt anspringen.

Die "Lesegeschwindigkeit" hat damit aber nichts zu tun. Die ist, bedingt durch Achitektur und physikalischen Eigenheiten, beim RAM extrem schnell und bei der Fesplatten dagegen eher langsam (im direkten Vergleich).
Hier muss man aber unterscheiden zwischen der Zugriffsgeschwindigkeit und der Übertragunggeschwindigkeit. Beides hängt aber nicht direkt von der Umdrehungsgeschwindigkeit der Scheiben ab.
Die Geschwindigkeit der Datenübertragung ließe sich durch schneller drehende Scheiben steigern (in der gleichen Zeit rauschen mehr Daten am Kopf vorbei), in der Regel wird aber einfach die Dichte der Daten erhöht, das führt zum gleichen Effekt.

Die Zugriffsgeschwindigkeit: Ich habe früher in einem Werbestudio gejobbt. Da war Internet noch out und 200 MB Festplatten riiiieeeeesig. Und die hatten damals für Fotozeugs eine Platte die war auf schnellen Datenzugriff optimiert indem sie viel mehr Scheiben hatte als die 'normalen' Festplatte. Dadurch hatte sie auch mehr Lese-/Schreibköpfe und somit im Zugriff schneller, da diese schneller an der benötigten Position waren.


So, zurück zu deiner ersten Frage:
Überleg dir mal was eine Datenbankabfrage auf der Datenbank tatsächlich macht. Vor allem wenn ein Index auf der einschränkenden Spalte liegt.


Gruß
Sparrow
sparrow ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 15.02.2010, 18:34 Nach oben    #14
Erfahrener Benutzer
 
Registriert seit: 16.08.2008
Ort: Mecklenburg-Vorpommern
Beiträge: 314
Standard

Zitat:
Vor allem wenn ein Index auf der einschränkenden Spalte liegt.
Die DB sucht im Index nach dem entsprechenden Eintrag. Der Eintrag zeigt auf die Stelle, an der die tatsächlichen Daten sich befinden. Falls die Daten nicht komplett aus dem Index gelesen werden können, holt man sie aus der entsprechenden Datei. Das wird alles auf Platte gemacht - es sei denn wir haben eine Memory-Table.

Was die Hardware aber allgemein angeht, kann ich nicht wirklich viel mitreden, dafür lernt man immer wieder was dazu. Danke für die Erläuterungen!
Sekundentakt ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 15.02.2010, 19:08 Nach oben    #15
Sesselkleber
 
Benutzerbild von sparrow
 
Registriert seit: 17.01.2005
Beiträge: 626
Standard

Ich will hier auch nicht zu Oberlehrerhaft rüberkommen ;)

Also ich sehe das mit der Datenbankabfrage in etwa so:

SQL-Anfrage kommt beim Server an.
Server untersucht die Abfrage (Syntax, Tabellen/Spalten vorhanden, etc.)
Server erstellt einen Plan für die Abfrage
Server führt Abfrage gemäß Plan aus
Server liefert ein Resultat bestehend aus Tupel über die iteriert werden kann.
Je nach Datenbank und Art der Abfrage ist es übrigens unterschiedlich wann tatsächlich der erste Datensatz zurück kommt. Entweder dann wenn der erste Datensatz gefunden wurde oder sobald die komplette Abfrage abgearbeitet wurde.

So, zurück zu deiner Problemstellung. Es kommt tatsächlich stark auf die Umgebung an in der das DBMS eingesetzt wird. Um sich Gedanken darüber machen zu können wie man das ganze Beschleunigen kann müsste man zuerst herausfinden wo genau eigentlich der Flaschenhals sitzt der überhaupt Zeit kostet.

Mir fällt auf jeden Fall im Augenblick nicht ein warum das Abfeuern von 2 Abfragen das Auslesen Beschleunigen sollte, denn dabei handelt es sich ja in der Regel nicht um einen 'teuren' Prozess was das Rechnen angeht. Wenn dann wartet das System wegen I/O-Sachen, und das wird durch mehrere gleichzeitige Abfragen vom gleichen Client mit Sicherheit nicht weniger.

Aber ausprobiert habe ich das natürlich gerade nicht ;)

Gruß
Sparroe
sparrow ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 15.02.2010, 21:00 Nach oben    #16
Neuer Benutzer
 
Registriert seit: 01.09.2009
Beiträge: 10
Standard

Bei MyISAM ist paralleles Lesen möglich, Inserts können bedingt ebenfalls parallel laufen.

//Edit: Huch, viel zu spät gepostet
Tiberius ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 18.02.2010, 18:54 Nach oben    #17
Erfahrener Benutzer
 
Registriert seit: 16.08.2008
Ort: Mecklenburg-Vorpommern
Beiträge: 314
Standard

Hallo Gemeinde,

ich bin da gerade auf ein grundlegendes Verständnisproblem meinerseits gestoßen.

Im Augenblick versuche ich folgendes:
Ich erzeuge verschiedene Runnable-Instanzen:

Code:
        Runnable firstTask = new Runnable() {
            @Override
            public void run() {
                 //...
                }

        Runnable secondTask = new Runnable() {
            @Override
            public void run() {
                 //...
                }

        Runnable lastTask = new Runnable() {
            @Override
            public void run() {
                 //...
                }
In jedem dieser Tasks befindet sich eine While-Schleife, die überprüft, ob der Rückgabewert des Aufrufes von .poll() einer ConcurrentLinkedQueue null ist. Wenn nicht, wird gearbeitet. Das Ganze ist eine Endlosschleife, bis die Queue leer ist.
Wenn der Rückgabewert aber null ist, wird das Ganze noch ein paar mal probiert, bis dann endgültig via break; die Schleife verlassen wird.
Ist der Thread, welcher diesen Task ausführt (aufgerufen via executorService.execute(anyTask)) dann auch grundsätzlich schon beendet, weil nichts mehr passiert?
Ich frage mich nämlich momentan, wie ich den Thread, welcher den Task - der im null-Fall nichts mehr zu tun hat - killen kann, ohne über executorService.shutdown() aufzurufen. Der Aufruf würde nämlich alle Tasks beenden.

Dankeschön! :)
Sekundentakt ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 19.02.2010, 06:51 Nach oben    #18
fka Gottzilla
 
Benutzerbild von The_S
 
Registriert seit: 02.02.2005
Ort: Würzburg
Beiträge: 753
Standard

Zitat:
Zitat von Sekundentakt Beitrag anzeigen
Das Ganze ist eine Endlosschleife, bis die Queue leer ist.
Haha . Endlosschleife ... bis ... . Nicht persönlich nehmen, aber die Aussage find ich cool ;) .

Zitat:
Zitat von Sekundentakt Beitrag anzeigen
(aufgerufen via executorService.execute(anyTask))
Warum gehst du über einen ExecutorService? Ich arbeite seit über 5 Jahre mit Java und habe noch nie in meinem Leben einen ExecutorService eingesetzt ;) .

Zitat:
Zitat von Sekundentakt Beitrag anzeigen
Ist der Thread, welcher diesen Task ausführt (aufgerufen via executorService.execute(anyTask)) dann auch grundsätzlich schon beendet, weil nichts mehr passiert?
Er soll beendet sein, weil nichts mehr passiert? Versteh ich nicht :-P . Ein Thread ist immer dann beendet, wenn die run-Methode des Runnable-Interfaces beendet ist.

Zitat:
Zitat von Sekundentakt Beitrag anzeigen
Ich frage mich nämlich momentan, wie ich den Thread, welcher den Task - der im null-Fall nichts mehr zu tun hat - killen kann
Ein Thread wird normalerweise nicht gekillt. Du setzt irgendwo eine Variable und der Thread überprüft in der run-Methode (z. B. bei jedem Schleifendurchgang), ob die Variable auf true oder false steht, und beendet dann dementsprechend die Schleife. Anschließend wird dann meist mehr oder weniger schnell (je nach dem wie viel Code nach der Schleife noch kommt) der Thread mit Abschluss der run-Methode beendet.

Zitat:
Zitat von Sekundentakt Beitrag anzeigen
ohne über executorService.shutdown() aufzurufen. Der Aufruf würde nämlich alle Tasks beenden.
Weiß immer noch nicht, warum du über einen ExecutorService gehst ...

Ein Tutorial zum Thema Threads von Sun:

Processes and Threads (The Java™ Tutorials > Essential Classes > Concurrency)

Kleiner Nachtrag, nicht dass das falsch verstanden wird: Ein ExecutorService macht bei mehreren Threads schon Sinn, aber braucht man imho eben nicht so oft. Bzw. ich nicht, da ich sowieso größtenteils mit EE oder ME Arbeite, und es da so etwas ohnehin nicht gibt/geben sollte ;)

Geändert von The_S (19.02.2010 um 08:48 Uhr)
The_S ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 19.02.2010, 10:29 Nach oben    #19
Erfahrener Benutzer
 
Registriert seit: 16.08.2008
Ort: Mecklenburg-Vorpommern
Beiträge: 314
Standard

Zitat:
Haha . Endlosschleife ... bis ... . Nicht persönlich nehmen, aber die Aussage find ich cool .
Vielleicht sollte ich doch noch mal über ein Mathematikstudium nachdenken, in dem ich widerlege, dass die Unendlichkeit wirklich unendlich ist... :).

Zitat:
Warum gehst du über einen ExecutorService? Ich arbeite seit über 5 Jahre mit Java und habe noch nie in meinem Leben einen ExecutorService eingesetzt .
Ich habe es in mehreren Tutorials und Video-Seminaren so erlebt und dachte mir, wenn ab Java 7 sowieso mehr Concurrency-Methoden auf dem "Markt" landen, sollte ich mich mit so etwas schon einmal anfreunden. :)

Zitat:
Er soll beendet sein, weil nichts mehr passiert? Versteh ich nicht :-P . Ein Thread ist immer dann beendet, wenn die run-Methode des Runnable-Interfaces beendet ist.
Wunderbar, danke für die Antwort! :) Ich nahm an, dass die run()-Methode zwar beendet ist, der Thread aber an sich irgendwie irgendwo noch weiterexistiert und darauf wartet, die run()-Methode noch mal aufrufen zu dürfen.

Zitat:
Ein Thread wird normalerweise nicht gekillt. Du setzt irgendwo eine Variable und der Thread überprüft in der run-Methode (z. B. bei jedem Schleifendurchgang), ob die Variable auf true oder false steht, und beendet dann dementsprechend die Schleife. Anschließend wird dann meist mehr oder weniger schnell (je nach dem wie viel Code nach der Schleife noch kommt) der Thread mit Abschluss der run-Methode beendet.
Ich mache das derzeit über ein break-Statement. Wenn ich eine gewisse Zeit lang "null" aus meiner Queue heraushole, wird ein Flag gesetzt, die While-Schleife verlassen und danach kommt die Sinnflut :).

Zitat:
Ein Tutorial zum Thema Threads von Sun:

Processes and Threads (The Java™ Tutorials > Essential Classes > Concurrency)
Danke für die Referenz! :) Die Unterscheidung von Thread und Process klingt interessant und gleichzeitig etwas fremd. Musstest Du schon mal mit Processes arbeiten?
Sekundentakt ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 19.02.2010, 11:12 Nach oben    #20
fka Gottzilla
 
Benutzerbild von The_S
 
Registriert seit: 02.02.2005
Ort: Würzburg
Beiträge: 753
Standard

Zitat:
Zitat von Sekundentakt Beitrag anzeigen
Wunderbar, danke für die Antwort! Ich nahm an, dass die run()-Methode zwar beendet ist, der Thread aber an sich irgendwie irgendwo noch weiterexistiert und darauf wartet, die run()-Methode noch mal aufrufen zu dürfen.
kA wie sich der ExecutorService da verhält, aber bei einem gewöhnlichen Thread wartet niemand darauf, dass die run-Methode noch einmal ausgeführt wird. Was ist überhaupt das eigentliche Problem? Oder konnten wir das jetzt schon lösen ?

Zitat:
Zitat von Sekundentakt Beitrag anzeigen
Danke für die Referenz! Die Unterscheidung von Thread und Process klingt interessant und gleichzeitig etwas fremd. Musstest Du schon mal mit Processes arbeiten?
Nein, noch nicht. Bei mir ist wie gesagt ohnehin recht wenig mit Threads für meine tägliche Arbeit relevant .
The_S ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Antwort

Lesezeichen


Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)
 
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche

Forumregeln
Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus



Alle Zeitangaben in WEZ +1. Es ist jetzt 12:23 Uhr.


Powered by vBulletin® Version 3.8.4 (Deutsch)
Copyright ©2000 - 2010, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.3.0

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47