Frage

Ich habe ein multithreaded Server C ++ Programm, das MSXML6 verwendet und analysiert kontinuierlich XML-Nachrichten, gilt dann ein vorbereitete XSLT-Transformation Text zu erzeugen. Ich bin dieses mit 4 CPUs auf einem Server ausgeführt wird. Jeder Thread ist völlig unabhängig und verwendet ein eigenes Objekt verwandeln. Es gibt keine gemeinsame Nutzung von beliebigem COM-Objekten unter dem Threads.

Das funktioniert gut, aber das Problem ist die Skalierbarkeit. Bei der Ausführung:

  1. mit einem Thread, bekomme ich etwa 26 Parse + Transformationen pro Sekunde pro Thread.
  2. mit 2 Fäden, bekomme ich etwa 20 / s / Gewinde,
  3. mit 3 Fäden, 18 / s / Faden.
  4. mit 4 Fäden, 15 / s / Faden.

Mit nichts zwischen Threads geteilt ich erwartet hatte nahezu lineare Skalierbarkeit, so dass es 4-mal schneller mit 4 Threads sein sollte als mit 1. Stattdessen ist es nur 2,3-mal schneller.

Es sieht aus wie ein klassisches Konfliktproblem. Ich habe Programme geschrieben Test die Möglichkeit des Anstoßes zu beseitigen in meinem Code zu sein. Ich bin mit der DOMDocument60 Klasse anstelle des FreeThreadedDOMDocument ein, um unnötige Sperren zu vermeiden, da die Dokumente nicht zwischen Threads gemeinsam genutzt werden. Ich sah hart für jeden Beweis von Cache-Zeile False Sharing und es gibt keine, zumindest in meinem Code.

Ein weiterer Hinweis, die Kontext-Switch Rate> 15k / s für jeden Thread. Ich bin die Schuldige zu raten ist der COM-Speicher-Manager oder die Speicher-Manager in MSXML. Vielleicht hat es eine globale Sperre, die erworben werden muss und für jeden Speicher alloc / Freigabe freigegeben. Ich kann einfach nicht glauben, dass in der heutigen Zeit, der Speicher-Manager nicht in einer Art und Weise geschrieben, die gut in multithreaded Multi-CPU-Szenarien skaliert werden kann.

Hat jemand eine Idee hat, was diese Behauptung verursacht oder wie es zu beseitigen?

War es hilfreich?

Lösung 3

Danke für die Antworten. Ich landete eine Mischung aus den beiden Vorschlägen der Umsetzung auf.

habe ich eine COM + ServicedComponent in C #, beherbergte es als separater Server-Prozess unter COM + und verwendet, um die XslCompiledTransform die Transformation auszuführen. Der C ++ Server eine Verbindung zu diesem externen Prozess COM und sendet es die XML und den transformierten String zurückkommt. Dies verdoppelt die Leistung.

Andere Tipps

Es ist ziemlich üblich, für Heap-basierte Speicher-Manager (Ihre grundlegende malloc / free) einen einzelnen Mutex zu verwenden, gibt es ziemlich gute Gründe dafür: a. Heap-Speicherbereich ist eine einzige zusammenhängende Datenstruktur

Es gibt alternative Speichermanagementstrategien (zum Beispiel hierarchischer Verteilern), die diese Einschränkung nicht hat. Sie untersuchen sollen den allocator von MSXML verwendet anpassen.

Alternativ sollten Sie untersuchen, aus einer Multi-Thread-Architektur zu einer Multi-Prozess-Architektur, mit separaten Prozessen für jeden MSXML Arbeiter weg bewegen. Da Ihre MSXML Arbeiter nimmt String-Daten als Eingang und Ausgang, müssen Sie nicht auf ein Serialisierung Problem.

Zusammengefasst:. Verwenden, um eine Multi-Prozess-Architektur, es ist eine bessere Passform für Ihr Problem, und es wird besser skalieren

MSXML verwendet BSTRs, die eine globale Sperre in seiner Heapverwaltung verwenden. Es verursacht uns eine Tonne Probleme für eine massiv Multi-User-App vor ein paar Jahren.

Wir haben unsere Verwendung von XML in unserer App entfernt, können Sie nicht in der Lage sein, dies zu tun, so dass Sie vielleicht besser dran, einen alternativen XML-Parser verwenden.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top