Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Hat jemand schon eine Dateisuche für Multicore geschrieben? (https://www.delphipraxis.net/101575-hat-jemand-schon-eine-dateisuche-fuer-multicore-geschrieben.html)

Dezipaitor 15. Okt 2007 20:33


Hat jemand schon eine Dateisuche für Multicore geschrieben?
 
Hi,

es gibt ja eine Menge Threads zum Thema FindFirst. Also dir Datei- und Ordnerauflistung oder -Suche.
Jedoch sind die alle nur für einen Kern.

Die Frage ist daher, wer hat schonmal, oder wer kann sich ein Konzept vorstellen, FindFirst für Multicore Prozessoren zu nutzen.

Reicht es einfach stupide mehrere Threads zu erstellen und diese werden dann auf verschiedene Kerne verteilt, ohne dass man extra Sachen macht? Also verteilt Windows Threads automatisch auf verschiedene Kerne?
Dann wäre es mehr oder weniger einfach eine Multithreadsuche zu erstellen.

Irgendwelche Vorschläge?

gsh 15. Okt 2007 20:38

Re: Hat jemand schon eine Dateisuche für Multicore geschrieb
 
jo es ist so einfach:
1 Thread (z.b. Hauptthread) = SingleCore nutzung
2 Threads = DualCore
4 Threads = QuadCore

OregonGhost 15. Okt 2007 20:41

Re: Hat jemand schon eine Dateisuche für Multicore geschrieb
 
Grundsätzlich verteilt Windows das schon und man sollte da nicht allzuviel reinpfuschen. Aber andererseits kannst du natürlich problemlos die Prozessoraffinität jedes einzelnen Threads einstellen, so dass jeder Thread definitiv auf einem eigenen Kern/Prozessor läuft, das ist gar nicht so kompliziert, wie es sich vielleicht anhört. Vergiss dabei jedoch folgendes nicht:
Die Suche greift auf den Datenträger zu. Wenn mehrere Threads gleichzeitig an ganz verschiedenen Orten suchen, kann die Zugriffszeit sich dramatisch erhöhen. Den Flaschenhals beim Suchen stellt ohnehin nicht die Rechenzeit da (was Multithreading ja verbessern würde), sondern die Wartezeit. Insofern bezweifle ich einen übermäßigen Performance-Anstieg ohnehin, aber ich bin gespannt auf deine Testergebnisse, so sie kommen :)

sirius 15. Okt 2007 20:43

Re: Hat jemand schon eine Dateisuche für Multicore geschrieb
 
Zitat:

Wenn mehrere Threads gleichzeitig an ganz verschiedenen Orten suchen
Und bei verschiedenen Platten?

C.Schoch 15. Okt 2007 20:51

Re: Hat jemand schon eine Dateisuche für Multicore geschrieb
 
Bei verschiedene physikalischen Platten bist du im optimalen Fall doppelt so schnell, das Suche nicht sequentiell sondern parallel abgearbeitet wird.
Kann ich selbst bestätigen

OregonGhost 15. Okt 2007 20:53

Re: Hat jemand schon eine Dateisuche für Multicore geschrieb
 
Klar, das ist so. Die große Frage ist halt, ob die explizite Aufteilung auf mehrere Kerne hier so viel bringt oder ob es nicht ausreicht, Windows einfach machen zu lassen, weil die Suchthreads so oder so die meiste Zeit auf die Festplatte(n) warten.

Dezipaitor 15. Okt 2007 22:07

Re: Hat jemand schon eine Dateisuche für Multicore geschrieb
 
Also ich kann definitv sagen, das Windows Vista meinen Quadcore bei der Suche und auch bei der Änderung von Dateisicherheiten nutzt.
Alle Kerne sind da immer gut 2/3 ausgelastet. Man kann schon garnicht mehr nebenher was machen. Ich entferne daher immer 1 oder 2 Kerne vom Explorer, damit ich weitermachen kann.

Jetzt ist nur die Frage, wie man den Algorithmus erstellt.
Ich hätte folgenden Vorschlag:


1a. Hauptthread (oder eigener neuer Thread) durchsucht das Ziel nach allen Verzeichnissen auf allen Ebenen. Es sucht nur nach Ordner
und setzt diese in eine Liste. Jeder Eintrag enthält einen vollständigen Pfad. Gibt es keine Ordner mehr, wartet der Thread
auf die anderen Threads. Dieser Thread kann auch die anderen Threads beenden, wenn er beendet wird (durch Nachricht).
1b. Threads erstellen. Anzahl = Kerne
2. Hier ist das Problem:
Die anderen Threads starten nach einer gewissen Zeit oder Anzahl von Ordnern, indem sie aus der Liste Ordner entnehmen (diese Löschen)
und darin nach Dateien suchen (oder alle durchgehen, je was gewünscht wird)
Der Zugriff auf die Liste muss natürlich synchronisiert werden.
3. Jeder Thread enthält eine eigene Gefundenliste, die die Pfade zu den gesuchten Dateien enthält.
Es gibt auch die Alternative, wenn z.B. etwas mit den Dateien gemacht werden soll (zB. Attribute angepasst), dann wird das über ein Callback (MultiThreading
muss der Aufgerufene beachten).


Ich meine diese Lösung ist nur ein Ansatz. Es könnte z.B. bei sehr vielen Ordnern Probleme geben, wenn diese nur wenige Dateien haben. Dann warten die anderen Threads ständig auf, dass neue Ordner in die Liste kommen.
Wie man jedoch mehrere Threads auf die Ordnersuche schickt, kann ich mir derzeit nicht vorstellen.

Irgendwelche Vorschläge?

Dezipaitor 16. Okt 2007 15:52

Re: Hat jemand schon eine Dateisuche für Multicore geschrieb
 
Die schnellste Suche ist immernoch die inidzierte Suche. Also ständiges indizieren im Hintergrund un speichern der Daten in einer DB.
Das funktioniert aber nicht für Situationen, in denen man Änderungen oder andere Besonderheiten (Sicherheit, Attribute) machen muss.

Ich habe mir nochmal den Vorgang überlegt:

1. (Hauptthread)
Initialisieren einer Liste für die Ordnernamen (absolut) (OL)
Initialisieren einer Critical Section CS für den Zugriff auf die OL.
Initialisieren einer Liste für die gefundenen Dateien (DL)
Initialisieren einer Critical Section CDL für den Zugriff auf die DL.
Initialisieren eines CallbackEvents (CE) für Lieferungen von gesuchten Dateien
Initialisiere eines Beenden Flag (BF) für das (vorzeitige) Beenden der Threads
Initialisieren von x ThreadState Flags (TS) für die Signalisierung, dass der Thread keine Aufgabe hat.

Einfügen der Suchordner in die OL. Hier können beliebig viele Startordner oder -laufwerke eingetragen werden.

x Threads erstellen, wobei x für die Anzahl der Kerne steht. Die Threads bekommen alle eine Suchmaske (z.B. *.*)
und ein Handle auf die CS, CDL, CE, BF und sein eigenes TS.

Der Hauptthread geht in einer Schleife mit folgender Endbedingung: Alle Threads sind arbeitslos, d.h. alle TS Flags
sind gesetzt. Wenn dies der Fall ist, wird BF gesetzt und per WaitFor Api auf die Threads gewartet und dann die Suche beendet

In der Schleife überwacht der Thread das CE. D.h. wenn das Event CE ausgelöst wird (oder es ein Timeout gibt),
dann wird CDL gesperrt und die DL wird kopiert, entleert und die CDL entsperrt. Die kopierten Dateien, werden dann als
Ereignis ausgegeben.


2. Threads
Jeder Thread wartet auf die CS. Wenn sie nicht gesperrt ist, dann sperrt er die CS, holt den ersten Ordnername und
entsperrt die CS. Der Thread läuft erst dann weiter, wenn die CS entsperrt wird. Das gilt für jedne der x Threads.
Fortgang:
Über FindFirst und Findnext werden die gesuchten Dateien in dem Unterordner aufgelistet. Zudem werden auch immer die
Ordner alle in einer Threadlokalen Liste gespeichert.
Wenn die Suche in diesem einen Unterordner beendet ist (keine weitere Suche in tieferen Unterordnern!!!), dann wird diese Ordnerliste
unter Sperrung und Entsperrung der CS in die OL eingefügt. Dies passiert einmalig nachdem es keine weiteren Dateien und Ordner gibt.
Dadurch wird verhindert, dass die CS ständig gesperrt werden muss.
Wird eine gewünschte Datei gefunden, dann wird sie auch ersteinmal in eine lokale Liste eingefügt und am Ende (genauso wie die OL)
über das CallbackEvent CE an den Hauptthread gesendet. Der Hauptthread bekommt daher eine Liste von gewünschten Dateien und kann
diese an die Anwendung über ein Ereignis übermitteln oder als Endergebnis zwischenspeichern.

Enthält die OL kein Ordner mehr, dann passiert folgendes*:
Der Thread setzt das ihm zugeordnete ArbeitslosFlag TS und überprüft weiter, ob Ordner in OL vorhanden sind (wie anfangs).
Wenn Ordner wieder enthalten sind, dann wird das Flag TS gelöscht, sonst wird überprüft, ob das Beenden Flag BF gesetzt ist.
Wenn nein, gehts zurück zu (*). Wenn ja, dann beendet sich der Thread.










So ich hoffe das war verständlich. Was haltet ihr davon? Irgendwelche Fehler?

sakura 16. Okt 2007 15:55

Re: Hat jemand schon eine Dateisuche für Multicore geschrieb
 
Mit FindFirst/FindNext auf mehrere Cores zu springen hilft nur, wenn Du auch mehrere physisch verschiedene Datenträger abfragst, sonst wirst Du insgesamt viel langsamer, da das ewige hin- und herspringen der Schreib/Leseköpfe der Datenträger verhältnismäßig sehr, sehr lange dauert. Es stellt sich also die Frage, ob Dein Ansatz überhaupt Sinn macht ;)

Nutze lieber, wie hier schon empfohlen den Windows Suchindex, lade Dir für Beispiele mal meine aktuellen EKON 11 Papiere aus meinem Blog ;)

...:cat:...

Dezipaitor 16. Okt 2007 16:08

Re: Hat jemand schon eine Dateisuche für Multicore geschrieb
 
Ich will diesen Ansatz nicht nur für die Suche sondern auch für die Verarbeitung von allen Dateien und UnterOrdner eines oder mehrere Ordner verwenden.
Da wird z.B. der Sicherheitsdeskriptor jedes Ordners und jeder Datei überprüft und gegebenfalls neu angepasst.

Phoenix 16. Okt 2007 16:37

Re: Hat jemand schon eine Dateisuche für Multicore geschrieb
 
Auch hier gilt: Befinden sich die Daten auf einer physikalischen Platte, würde ich es tunlichst vermeiden, mehrere Threads auf die Dateien loszulassen.

Ein Thread pro physikalisches Laufwerk ist da ideal.

Ggf. lohnt es sich jedoch, einen Thread die Daten lesen-, und ggf. mehrere Threads die gelesenen Daten auswerten zu lassen. Auch Schreibvorgänge sollten dann tunlichst nur in dem einem 'Zugriffs-'Thread pro Platte vorgenommen werden.

Dezipaitor 16. Okt 2007 17:52

Re: Hat jemand schon eine Dateisuche für Multicore geschrieb
 
Also ich hab mir mal die Vista Suche etwas genauer angeschaut und habe dazu einen großen nicht indizierten Ordner verwendet.

Suche nach *.hlp Dateien in nicht indizierten Ordner. Vor jeder Suche wird das Suchergebniss gelöscht, indem krz nach etwas anderem gesucht wird.
Folgendes Bild habe ich bekommen:

Kerne : Elemente gefunden : Zeit : Auslastung (Kernnummer)

4 : 250 : 2:18 : zuerst 60-80%(1), dann nach 5-10sek 5-10%(1), 15-25%(2-4)
2 : 250 : 2:30 : 25-40% (3,4)
1 : 250 : 2:06 : 70-100% (4)

Ich habe die Kernanzahl für den Prozess explorer.exe entsprechend eingestellt.
Ich habe jeden Test 2 mal durchgeführt und dann das Mittel gebildet.

Das Ergebnis ist wohl eindeutig, obwohl ich mir nicht erklären kann, warum 2 Kerne solange brauchen. Ich werde mal den Test bei Gelegenheit auch unter XP durchführen.

himitsu 30. Okt 2007 19:22

Re: Hat jemand schon eine Dateisuche für Multicore geschrieb
 
Zitat:

Zitat von Dezipaitor
Vor jeder Suche wird das Suchergebniss gelöscht, indem krz nach etwas anderem gesucht wird.

klappt nicht so ganz Windows is ins solchen Dingen nicht wirklich optimiert, das zeigt doch schon die zu hohe CPU-Auslastung.

außerdem werden Dateien und vorallem das das Dateisystem im RAM zwischengespeichert - siehe (System)FileCache
und speziell das Cachen des Dateisystems (Ordnerinhalte) kann nicht groß beeinflußt werden.

Zitat:

Das Ergebnis ist wohl eindeutig
wie eindeutig?
ich schau mir die Zeit an und was seh ich?
SingelCore ist schneller.

Zitat:

obwohl ich mir nicht erklären kann
das könnte vielleicht an der FileCache liegen.


PS: ein guter weg die FileCache zu leeren ist das System kurz in den Hibernate zu fahren, denn die Cache wird geflusht und/also nicht gespeichert und ist danach schon fast leer (bis auf das was nach dem Hochfahren wieder reingeladen wurde).

ist och die einzige Möglichkeit ohne direkt in das FileCacheManagement einzugreifen (was eh kaum Möglich ist)

also soviele Prozesse wie möglich beenden (möglichst bis auf das Testprog)
und dann vor jeder Messung kurz aus-ein ... ein/zwei minuten warten, damit sich das System beruhigt und immer etwa gleiche Wartezeiten einhalten

Dezipaitor 31. Okt 2007 07:38

Re: Hat jemand schon eine Dateisuche für Multicore geschrieb
 
Zitat:

Zitat von himitsu
Zitat:

Zitat von Dezipaitor
Vor jeder Suche wird das Suchergebniss gelöscht, indem krz nach etwas anderem gesucht wird.

klappt nicht so ganz Windows is ins solchen Dingen nicht wirklich optimiert, das zeigt doch schon die zu hohe CPU-Auslastung.

Das war doch das Ziel! Die hohe CPU Auslastung verriet mir, dass kein Index der Dateien vorlag. Zudem war die Plattenaktivität dadurch hoch.

Zitat:

Zitat von himitsu
außerdem werden Dateien und vorallem das das Dateisystem im RAM zwischengespeichert - siehe (System)FileCache
und speziell das Cachen des Dateisystems (Ordnerinhalte) kann nicht groß beeinflußt werden.

Die getestete Platte ist eine SATA im Wechselrahmen und daher für schnelles Herausziehen optimiert.
Abgesehen von diesem Fakt, habe ich die Tests doppelt durchlaufen und beide Male immer sehr ähnliche Ergebnisse erzielt.

Zitat:

Zitat von himitsu
Zitat:

Zitat von Dezipaitor
Vor jeder Suche wird das Suchergebniss gelöscht, indem krz nach etwas anderem gesucht wird.

klappt nicht so ganz Windows is ins solchen Dingen nicht wirklich optimiert, das zeigt doch schon die zu hohe CPU-Auslastung.

Zitat:

Zitat von himitsu
Zitat:

Das Ergebnis ist wohl eindeutig
wie eindeutig?
ich schau mir die Zeit an und was seh ich?
SingelCore ist schneller.

Natürlich eindeutig auf den Sieg für SingleCore. Ich habe ja nicht geschrieben, dass die Ergebnisse gleich sind.

Zitat:

Zitat von himitsu
Zitat:

obwohl ich mir nicht erklären kann
das könnte vielleicht an der FileCache liegen.

Bitte reiss meine Sätze nicht auseinander und zitiere sie dann. Wenn das Original nicht drüber stehen würde, würde man nicht erfahren, dass ich mir nicht erklären kann warum 2 Kerne länger brauchen als 4 Kerne.
Vielleicht muss man hunderte von Testdurchläufen machen, um genauerere und aussagekrätigere Ergebnisse zu machen. Aber das mache ich nicht für eine solche kleine Sache.




PS: ein guter weg die FileCache zu leeren ist das System kurz in den Hibernate zu fahren, denn die Cache wird geflusht und/also nicht gespeichert und ist danach schon fast leer (bis auf das was nach dem Hochfahren wieder reingeladen wurde).

ist och die einzige Möglichkeit ohne direkt in das FileCacheManagement einzugreifen (was eh kaum Möglich ist)

also soviele Prozesse wie möglich beenden (möglichst bis auf das Testprog)
und dann vor jeder Messung kurz aus-ein ... ein/zwei minuten warten, damit sich das System beruhigt und immer etwa gleiche Wartezeiten einhalten



Alle Zeitangaben in WEZ +1. Es ist jetzt 13:49 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz