Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

[java] RMI performance probleem.

Pagina: 1
Acties:
  • 297 views sinds 30-01-2008
  • Reageer

  • justice strike
  • Registratie: Juni 2001
  • Laatst online: 17-11 18:23
ik heb een interessant probleem. Ik heb een programma gemaakt welke werkt op meerdere machines.

Elke machine(node) genereert een X aantal (worker) threads. Er is een master node welke de jobs genereert (met een global queue) (ook deze heeft worker threads). Elke thread haalt de jobs op bij de global queue en begint ze dan uit te voeren. Als de queue leeg is dan locken de threads totdat de queue weer gevult is (dit werkt naar behoren)

Het probleem: Vanaf 4/8 nodes maakt het weinig meer uit of er 1 of meer threads draaien per node (elke node heeft 2 cpus). Vreemd genoeg gaat de performance wel weer omhoog als er een node bijgeplaatst wordt. 16 nodes met 1 thread performen dus beter dan 8 nodes met 2 threads.

Ik zat zelf te denken dat de master node misschien teveel moet doen (omdat de workers ook werken op dezelfde thread) maar ook dit is niet de reden. Zelfs als de master node alleen maar zorgt voor de global queue zie je hetzelfde patroon (dat vanaf een bepaalt aantal nodes het niet uitmaakt hoeveel threads er zijn)

Ik begrijp niet precies waarom er wel performance gain is bij meerdere nodes, maar haast geen bij extra threads. Terwijl er tot de 4 nodes juist wel flinke performance gain is bij 2 threads tov 1 thread. Iemand een idee?

[ Voor 3% gewijzigd door justice strike op 20-01-2008 00:46 ]

U can call me sir.... or justice as long as u bow down ;)


  • voodooless
  • Registratie: Januari 2002
  • Laatst online: 08:29

voodooless

Sound is no voodoo!

Hoeveel RMI verkeer heb je tussen master en nodes, en waneer? Als ze enkel een job uit een queue halen kan ik me niet voorstellen dat RMI een probleem zou moeten zijn.

Do diamonds shine on the dark side of the moon :?


  • justice strike
  • Registratie: Juni 2001
  • Laatst online: 17-11 18:23
ze halen enkel een job uit de queue, als de job klaar is dan stoppen ze weer een answer terug in de queue.

elke node checked ook nog om de seconde of de applicatie niet gekilled wordt.

Ik denk zelf ook niet dat het het verkeer is, want dan zou je dezelfde peformance zien voor 8 nodes 2 threads en 16 nodes 1 thread (het aantal working threads is dan namelijk hetzelfde ==> het aantal queue requests is dan ook hetzelfde) dit is helaas niet het geval. Het moet wel iets zijn wat te maken heeft met de implementatie van rmi daar ik dezelfde problemen op 1 node (1 en 2 threads) niet zie daar is de performance gain aanzienlijk en vrijwel gelijk aan 2 nodes met 1 thread.

U can call me sir.... or justice as long as u bow down ;)


  • voodooless
  • Registratie: Januari 2002
  • Laatst online: 08:29

voodooless

Sound is no voodoo!

Heb je al wat profiling gedaan?

Do diamonds shine on the dark side of the moon :?


  • justice strike
  • Registratie: Juni 2001
  • Laatst online: 17-11 18:23
profiling gaat helaas wat lastig. De nodes zijn namelijk niet direct bereikbaar. de classes worden door een tool gedistribueerd en de jvm's kunnen hun output daarom ook niet in een file kwijt (althans, misschien kunnen ze dat wel, maar ik kan niet bij het profiling bestand) of er moet een manier zijn om het over de standard output te gooien.

[ Voor 7% gewijzigd door justice strike op 20-01-2008 18:17 ]

U can call me sir.... or justice as long as u bow down ;)


  • voodooless
  • Registratie: Januari 2002
  • Laatst online: 08:29

voodooless

Sound is no voodoo!

Met jconsole kun je misschien wel iets doen, in ieder geval CPU tijden, memory, theads. Je kun daar ook zelf monitoring spul bij maken voor je eigen componenten. Een feest is het niet, maar misschien wel het proberen waard.

Do diamonds shine on the dark side of the moon :?


  • justice strike
  • Registratie: Juni 2001
  • Laatst online: 17-11 18:23
voodooless schreef op zondag 20 januari 2008 @ 20:47:
Met jconsole kun je misschien wel iets doen, in ieder geval CPU tijden, memory, theads. Je kun daar ook zelf monitoring spul bij maken voor je eigen componenten. Een feest is het niet, maar misschien wel het proberen waard.
ook voor jconsole heb je access nodig tot de jvm. maar ik begrijp dus dat er weinig op zit dan te profilen.

U can call me sir.... or justice as long as u bow down ;)


  • voodooless
  • Registratie: Januari 2002
  • Laatst online: 08:29

voodooless

Sound is no voodoo!

Misschien moet je dan maar simpel standard output profilen met wat simpele debugging output (als het geheel niet te complex is natuurlijk).

Do diamonds shine on the dark side of the moon :?


  • justice strike
  • Registratie: Juni 2001
  • Laatst online: 17-11 18:23
voodooless schreef op zondag 20 januari 2008 @ 21:51:
Misschien moet je dan maar simpel standard output profilen met wat simpele debugging output (als het geheel niet te complex is natuurlijk).
hmm hoe bedoel je profilen met standaard output? bedoel je een timer voor elke functie zetten?

ansich is er niets complex. Er zijn workers die iets ophalen en het verwerken en het antwoord retourneert. veel simpeler kan niet.

[ Voor 3% gewijzigd door justice strike op 20-01-2008 22:11 ]

U can call me sir.... or justice as long as u bow down ;)


  • Jaap-Jan
  • Registratie: Februari 2001
  • Laatst online: 20-11 18:44
Ik denk dat hij good old System.out.println() bedoeld met System.nanoTime() of System.currentTimeMillis(). :)

| Last.fm | "Mr Bent liked counting. You could trust numbers, except perhaps for pi, but he was working on that in his spare time and it was bound to give in sooner or later." -Terry Pratchett


  • justice strike
  • Registratie: Juni 2001
  • Laatst online: 17-11 18:23
Jaap-Jan schreef op zondag 20 januari 2008 @ 22:13:
Ik denk dat hij good old System.out.println() bedoeld met System.nanoTime() of System.currentTimeMillis(). :)
Dat dacht ik dus ook al ;) alleen probleem is dat je dat niet op die manier kunt vinden. De implementatie van het probleem is namelijk hetzelfde. Ik zou niet weten waar ik op zou moeten zoeken, datgene wat ik gedacht heb dat blijkt het niet te zijn.

De threaded versie is precies hetzelfde als de multiple node versie. Als er ergens performance verlies optreed dan zou dat ergens in de communicatie moeten zijn, of met de masternode.

hmm ik probeer het even heel helder uit te leggen, mocht dit niet duidelijk zijn zeg het dan even want ik geloof niet dat ik het probleem zal vinden in profiling.

datgene wat werk verricht is een worker thread welke gedraait wordt op de jvm. Een node in de cluster maakt gebruik van 2 cpu's dus per saldo kun je 2 threads (met enige overhead) kunnen draaien op een node en goede speedup verwachten.

Dit gaat ook gewoon goed totdat je bij de 4~8 nodes komt waarna de speedup bij het toevoegen van een node wel nog omhoog gaat, maar het niet meer uitmaakt of er 1 of 2 threads per node werken.

Ik begrijp dit niet echt, immers kunnen er per node 2 threads goed draaien met peformance gain. Wat maakt het dan voor een verschil uit of je 16 single threaded nodes gebruikt of 8 dual threaded nodes. Immers kom je uit op het zelfde aantal threads. De communicatie die gedaan moet worden is ook hetzelfde (de threads zorgen elk zelf voor de communicatie naar de master queue) Kortom, er zou niets moeten zijn wat de performance in de weg zit. Toch blijkt het wel zo te zijn.

[ Voor 87% gewijzigd door justice strike op 20-01-2008 22:44 ]

U can call me sir.... or justice as long as u bow down ;)


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 04:35
Even voor de duidelijkheid: het is dus zo dat als je twee nodes met elk twee threads gebruikt, dit wél twee keer zo snel is als twee nodes met elk één thread? Anders lijkt me dat je per ongeluk je worker thread in een synchronized block hebt gezet ofzo.

  • justice strike
  • Registratie: Juni 2001
  • Laatst online: 17-11 18:23
Soultaker schreef op zondag 20 januari 2008 @ 23:28:
Even voor de duidelijkheid: het is dus zo dat als je twee nodes met elk twee threads gebruikt, dit wél twee keer zo snel is als twee nodes met elk één thread? Anders lijkt me dat je per ongeluk je worker thread in een synchronized block hebt gezet ofzo.
niet 2 keer zo snel, maar wel aanzienlijk sneller (65% ofzo). maar je hebt dus gelijk, 2 nodes met 2 threads presteerd aanzienlijk beter dan 2 nodes met 1 thread.

Echter 8 nodes met 2 threads (16 threads in totaal) presteerd echter nagenoeg hetzelfde als 8 nodes met 1 thread


1 thread2 threads
1 node45.542 sec25.786 sec
2 node25.902 sec21.599 sec
4 node17.376 sec15.51sec
8 node13.825 sec15.576 sec


//edit ik ga even gemiddelden nemen want dit is niet heel representatief, het geeft echter wel een goed beeld van het probleem.

[ Voor 38% gewijzigd door justice strike op 20-01-2008 23:57 ]

U can call me sir.... or justice as long as u bow down ;)


  • MNeMoNiCS
  • Registratie: Mei 2002
  • Laatst online: 16-10-2012
Is het misschien mogelijk om per node/thread (in een file of naar de console) weer te geven
  • hoeveel jobs een node/thread heeft uitgevoerd?
  • wat de gemiddelde executie tijd per job was?

  • Bob
  • Registratie: Mei 2005
  • Laatst online: 21:06

Bob

Als die data representatief is zit je met een stevige overhead door het te threaden, 8 nodes 1 thread is sneller dan 8 nodes 2 threads. Daar moet een foutje zitten :)
Hoe verdeelt een node zijn werk nog eens over zijn eigen threads?

  • justice strike
  • Registratie: Juni 2001
  • Laatst online: 17-11 18:23
Bob schreef op maandag 21 januari 2008 @ 00:25:
Als die data representatief is zit je met een stevige overhead door het te threaden, 8 nodes 1 thread is sneller dan 8 nodes 2 threads. Daar moet een foutje zitten :)
Hoe verdeelt een node zijn werk nog eens over zijn eigen threads?
nee, de node initialiseert 2 threads (initialisatie wordt niet meegenomen in de tijd) workers gaan daarna zelfstandig naar de queue om werk te halen.

zoals ik al zei, ik ga even gemiddeldes nemen want deze tabel is niet helemaal representatief, maar schept wel een beeld van het probleem dat ik heb. Het moet echt iets heel triviaals zijn aangezien alles wel netjes werkt met minder threads.

Het probleem is overigens een 15 piece puzzle opgelost met behulp van een manhattan distance en een Iterative Deepening A* algorithm.

U can call me sir.... or justice as long as u bow down ;)


  • flowerp
  • Registratie: September 2003
  • Laatst online: 11-09 18:20
justice strike schreef op zondag 20 januari 2008 @ 23:32:
1 thread2 threads
1 node45.542 sec25.786 sec
2 node25.902 sec21.599 sec
4 node17.376 sec15.51sec
8 node13.825 sec15.576 sec


//edit ik ga even gemiddelden nemen want dit is niet heel representatief, het geeft echter wel een goed beeld van het probleem.
Rottig probleem ja. Je ziet zo zonder gemiddelden ook al dat de efficiency afneemt bij het draaien van de threads op 2 cpus per enkele node vs 1 cpu per node bij 2 nodes. Waarschijnlijk treed het effect ook al (gemiddeld) op bij een kleiner aantal nodes, maar is het effect dan gewoon klein.

Je zou inderdaad denken aan een synchronized iets ergens. Soms weet je ook helemaal niet dat er voor iets een lock gebruikt wordt. Dit kan b.v. net zo goed een functie wat dieper in een library call zijn. Is het mogelijk om 2 VM's per node te draaien? Dan zou je mogelijk eventuele OS dingen (b.v. shared buffer, kernel primitive ergens) uit kunnen sluiten.

Een iets ingewikkeldere setup is het draaien van de threads via hun eigen classloader. Static variables alsmede instances zijn dan afgeschermd van elkaar per thread (en juist op deze dingen synchronized er wellicht iets). Java EE gebruikt deze techniek bijvoorbeeld om binnen 1 VM meerdere applicaties min of meer van elkaar te scheiden.

It's shocking to find how many people do not believe they can learn, and how many more believe learning to be difficult.


  • Bob
  • Registratie: Mei 2005
  • Laatst online: 21:06

Bob

Kan je het cpu gebruik van de twee cpu's/cores van een node in de gaten houden? Misschien slokt er nog iets anders cpu tijd op? Een of andere method die ook threaded wordt benaderd en er plots heel lang over doet?

edit: nvm, mijn idee zal ook weer neerkomen op een lock door een slechtgeplaatste synchronized

[ Voor 18% gewijzigd door Bob op 21-01-2008 00:37 ]


  • justice strike
  • Registratie: Juni 2001
  • Laatst online: 17-11 18:23
flowerp schreef op maandag 21 januari 2008 @ 00:33:
[...]


Rottig probleem ja. Je ziet zo zonder gemiddelden ook al dat de efficiency afneemt bij het draaien van de threads op 2 cpus per enkele node vs 1 cpu per node bij 2 nodes. Waarschijnlijk treed het effect ook al (gemiddeld) op bij een kleiner aantal nodes, maar is het effect dan gewoon klein.

Je zou inderdaad denken aan een synchronized iets ergens.
de performance is nagenoeg hetzelfde in de instantie die jij noemt (het is 25 seconden nogwat niet 25000 seconden ;))

Iedere keer bij het verleggen van de bound (iterative deepening dus gaat steeds verder zoeken) wordt er idd door alle workers gewacht totdat alle jobs klaar zijn. Dit gebeurt onder water met locks. Dat is ansich ook niet het probleem. De threads locken als er geen jobs meer in de queue zitten, deze worden weer gevult door de master node als de volgende bound weer begint. Als er dus nog 1 job bezig is dan kan het zijn dat er 31 workers zitten te wachten, tja dan heb je peformance verlies.

Dat werkt naar behoren, maar ik kan niet het verschil in performance verklaren voor 16 nodes 1 thread en 8 nodes 2 threads. of zoals in de tabel tussen 2 nodes met 2 threads, en 4 nodes met 1 thread. Je zou namelijk verwachten dat de performance nagenoeg hetzelfde is. In sommige gevallen is het verschil zelfs heel extreem.

[ Voor 17% gewijzigd door justice strike op 21-01-2008 00:53 ]

U can call me sir.... or justice as long as u bow down ;)


  • flowerp
  • Registratie: September 2003
  • Laatst online: 11-09 18:20
Bob schreef op maandag 21 januari 2008 @ 00:36:
edit: nvm, mijn idee zal ook weer neerkomen op een lock door een slechtgeplaatste synchronized
Een slecht geplaatste synchronized zal je niet echt terug zien in het CPU gebruik ;)

Het keyword hier is wellicht "lock contention". Niet dat ik zeg dat dat perse het probleem van de TS is, maar dat is eigenlijk een algemene oorzaak wat wel vaak van toepassing is. Ik vermoed dat lock contention met de opkomst van many-core CPUs een steeds belangrijkere issue gaat worden. Ik zie het zelf ook wel vaker op systemen; de IO is niet maximaal belast. De CPU is niet maximaal belast. En -toch- duurt iets lang.

TS zou dus even zich kunnen inlezen in tools om lock contention te monitoren. Jconsole biedt wat mogelijkheden en de IBM JVM biedt ook wat moois daarvoor. Je zou dan de (gemiddelde) lock contention kunnen meten per thread als 1 CPU per node gebruikt wordt en dat vergelijken met de lock contention per thread als 2 cpus per node gebruikt worden. Wijkt dit significant af dan is de conclusie wel duidelijk.

Is IO trouwens een issue? Een machine kan wel meerdere CPUs hebben, maar als het disk subsysteem de bottleneck is dan helpt dat niet heel erg veel. Als je dus 2 threads op 2 nodes laat draaien vs 2 thread op 1 node, kan er ook gewoon sprake van zijn dat je meer total power hebt in de 2 node situatie.

It's shocking to find how many people do not believe they can learn, and how many more believe learning to be difficult.


  • flowerp
  • Registratie: September 2003
  • Laatst online: 11-09 18:20
justice strike schreef op maandag 21 januari 2008 @ 00:46:
Dat werkt naar behoren, maar ik kan niet het verschil in performance verklaren voor 16 nodes 1 thread en 8 nodes 2 threads.
Er zit natuurlijk technisch gezien wel wat verschil. Een belangrijk verschil is dat 2 threads/1 node een address space sharen, terwijl 2 threads/2 nodes volledig van elkaar geïsoleerd zijn.

Qua (high level) software architecture maakt het misschien niet uit; je hebt een distributed pool van 16 threads, die elk volledig op zich zelf werken en voor wie het programmatisch ook niet uitmaakt of hun peers op dezelfde machine draaien of niet (aangezien ze alleen met de master communiceren).

Echter, het -zou- kunnen zijn dat er onbedoeld ergens gesynchronized wordt op iets. Binnen 1 enkele address space, en zeker binnen dezelfde class loader is dat gewoon een mogelijk effect. Omdat de threads niet direct instances met elkaar delen, zijn statics dan als eerste verdacht.

Zoals ik al eerder opmerkte; statistics over lock contention kunnen dan uitsluitsel geven, in ieder geval weet je dan of dit effect het veroorzaakt.

It's shocking to find how many people do not believe they can learn, and how many more believe learning to be difficult.


  • justice strike
  • Registratie: Juni 2001
  • Laatst online: 17-11 18:23
flowerp schreef op maandag 21 januari 2008 @ 00:54:
[...]
TS zou dus even zich kunnen inlezen in tools om lock contention te monitoren. Jconsole biedt wat mogelijkheden en de IBM JVM biedt ook wat moois daarvoor. Je zou dan de (gemiddelde) lock contention kunnen meten per thread als 1 CPU per node gebruikt wordt en dat vergelijken met de lock contention per thread als 2 cpus per node gebruikt worden. Wijkt dit significant af dan is de conclusie wel duidelijk.

Is IO trouwens een issue? Een machine kan wel meerdere CPUs hebben, maar als het disk subsysteem de bottleneck is dan helpt dat niet heel erg veel. Als je dus 2 threads op 2 nodes laat draaien vs 2 thread op 1 node, kan er ook gewoon sprake van zijn dat je meer total power hebt in de 2 node situatie.
Ik zat te denken aan een overload van de master node (die heeft namelijk ook 2 workers wat dus extra load met zich meebrengt) maar het opheffen van de 2 workers op de master node resulteren alsnog in dezelfde resultaten

overigens is het niet lineare character van de speedup niet het probleem. Alleen het verschil tussen 2 nodes 2 threads en 4 nodes 1 thread. Dit kan imho geen lock probleem zijn daar er in beide gevallen 4 threads zijn die aanspraak maken op dezelfde queue.

U can call me sir.... or justice as long as u bow down ;)


  • justice strike
  • Registratie: Juni 2001
  • Laatst online: 17-11 18:23
flowerp schreef op maandag 21 januari 2008 @ 01:03:
[...]


Er zit natuurlijk technisch gezien wel wat verschil. Een belangrijk verschil is dat 2 threads/1 node een address space sharen, terwijl 2 threads/2 nodes volledig van elkaar geïsoleerd zijn.
we posten even door elkaar heen ;)

Het probleem komt ook meer voort bij meerdere nodes. Overigens laat ik alles over het netwerk gaan, ook bij een single node oplossing zal hij dus aanspraak maken op een global queue. Maar zoals je ziet uit de tabel is een 2 node single thread oplossinge nagenoeg even snel als een single node double thread oplossing.
Qua (high level) software architecture maakt het misschien niet uit; je hebt een distributed pool van 16 threads, die elk volledig op zich zelf werken en voor wie het programmatisch ook niet uitmaakt of hun peers op dezelfde machine draaien of niet (aangezien ze alleen met de master communiceren).

Echter, het -zou- kunnen zijn dat er onbedoeld ergens gesynchronized wordt op iets. Binnen 1 enkele address space, en zeker binnen dezelfde class loader is dat gewoon een mogelijk effect. Omdat de threads niet direct instances met elkaar delen, zijn statics dan als eerste verdacht.
Ik ga nog even de workers code nog even doornemen, maar de enige plek waar ik uberhaupt locks gebruikt heb is in de queue. Het zal me niet verbazen dat java onder water locks gebruikt om i/o af te handelen, maar zou dat een steeds grotere rol innemen bij de toename van nodes?
Zoals ik al eerder opmerkte; statistics over lock contention kunnen dan uitsluitsel geven, in ieder geval weet je dan of dit effect het veroorzaakt.
ik ga dan toch even kijken of ik niet ergens profiling data kan krijgen.

U can call me sir.... or justice as long as u bow down ;)


  • Bob
  • Registratie: Mei 2005
  • Laatst online: 21:06

Bob

flowerp schreef op maandag 21 januari 2008 @ 00:54:
[...]


Een slecht geplaatste synchronized zal je niet echt terug zien in het CPU gebruik ;)
:X
Ik zal maar in mijn bed kruipen

  • justice strike
  • Registratie: Juni 2001
  • Laatst online: 17-11 18:23
ok

hier heb ik de gemiddelde getallen

1 thread2 threads
1 node44.405sec34.323sec
2 node26.552sec21.467sec
4 node17.485sec16.3352sec
8 node14.243sec15.471sec

U can call me sir.... or justice as long as u bow down ;)


  • voodooless
  • Registratie: Januari 2002
  • Laatst online: 08:29

voodooless

Sound is no voodoo!

Misschien kun je vaststellen hoeveel RMI verkeer er is tussen de host en de nodes?

Die lock op je queue is natuurlijk niet zo spannend als een job meerdere seconden duurt, maar wel de objecten die je met zo'n job op en neer aan het gooien bent. Misschien is dat wel juist de bottleneck?

RMI is niet zo vriendelijk voor netwerk IO :'(

[ Voor 7% gewijzigd door voodooless op 21-01-2008 10:30 ]

Do diamonds shine on the dark side of the moon :?


  • justice strike
  • Registratie: Juni 2001
  • Laatst online: 17-11 18:23
voodooless schreef op maandag 21 januari 2008 @ 10:24:
Misschien kun je vaststellen hoeveel RMI verkeer er is tussen de host en de nodes?

Die lock op je queue is natuurlijk niet zo spannend als een job meerdere seconden duurt, maar wel de objecten die je met zo'n job op en neer aan het gooien bent. Misschien is dat wel juist de bottleneck?

RMI is niet zo vriendelijk voor netwerk IO :'(
die gedachte had ik in het eerste opzicht ook, maar aangezien elke thread zijn eigen rmi calls maakt zou het niet zo gek veel moeten verschillen. Er worden namelijk in een situatie met een gelijk aantal threads een gelijk rmi calls moeten komen. (2 nodes 2 threads tegenover 4 nodes 1 thread)

U can call me sir.... or justice as long as u bow down ;)


  • voodooless
  • Registratie: Januari 2002
  • Laatst online: 08:29

voodooless

Sound is no voodoo!

Maar wel naar een enkele node, en niet maar 8 verschillende. Misschien dat dat toch wel uitmaakt.

Do diamonds shine on the dark side of the moon :?


  • justice strike
  • Registratie: Juni 2001
  • Laatst online: 17-11 18:23
voodooless schreef op maandag 21 januari 2008 @ 11:46:
Maar wel naar een enkele node, en niet maar 8 verschillende. Misschien dat dat toch wel uitmaakt.
ja, dat klopt ansich wel, maar het blijven uiteindelijk 8 threads die naar 1 node communiceren. Of die threads dan over 4 of 8 nodes verspreid zijn dat maakt weinig uit omdat de communicatie toch moet gebeuren.

U can call me sir.... or justice as long as u bow down ;)


  • voodooless
  • Registratie: Januari 2002
  • Laatst online: 08:29

voodooless

Sound is no voodoo!

Misschien dat 1:1 communicatie met RMI minder lastig is dan 1:n communicatie... Ik doe ook maar een wilde gok hoor ;) Ik vrees dat je zonder een beetje profilen toch in het duister zal blijven tasten met dit probleem.

Do diamonds shine on the dark side of the moon :?


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 04:35
Op zich leek me dit een nuttige suggestie:
flowerp schreef op maandag 21 januari 2008 @ 00:33:
Is het mogelijk om 2 VM's per node te draaien? Dan zou je mogelijk eventuele OS dingen (b.v. shared buffer, kernel primitive ergens) uit kunnen sluiten.
... maar eigenlijk verklaart het niet waarom de efficiëntie per node achteruit gaat als je meer nodes hebt. (Eventuele lock contention of gebrek aan geheugenbandbreedte of synchronisatie-overhead zou je op één node met twee processen al moeten hebben, en die zou niet groter moeten worden puur omdat er meer nodes bestaan.)

  • flowerp
  • Registratie: September 2003
  • Laatst online: 11-09 18:20
justice strike schreef op maandag 21 januari 2008 @ 02:33:
ok

hier heb ik de gemiddelde getallen

1 thread2 threads
1 node44.405sec34.323sec
2 node26.552sec21.467sec
4 node17.485sec16.3352sec
8 node14.243sec15.471sec
Hmmm, je ziet wel dat de speed-up per node toevoegen voor elke type belasting (1 thread vs 2 threads per node) eigenlijk nog niet eens zo dramatisch is:

speedup 1thread/nodespeedup 2threads/nodespeedup1 vs speedup2
1->2 nodes1.67 1.601.04
2->4 nodes1.52 1.311.16
4->8 nodes1.23 1.061.16


In beide gevallen, of je 1 thread per node gebruikt of 2 threads per node, neemt de speedup relatief gezien af. Als je van 2 naar 4 nodes gaat en daarna van 4 naar 8 nodes, is de relatieve speedup tussen de gevallen met 1 en 2 threads ondeling zelfs identiek 1.16.

Een andere aardige constante die opvalt is het delta tijd verschil tussen een zelfde aantal threads over een steeds groter aantal nodes:

2 threads: 1x2 vs 2x1 = 7.771s ~ 8 sec
4 threads: 2x2 vs 4x1 = 3.982s ~ 4 sec
8 threads: 4x2 vs 8x1 = 2.0922 ~ 2 sec

[ Voor 8% gewijzigd door flowerp op 21-01-2008 22:09 ]

It's shocking to find how many people do not believe they can learn, and how many more believe learning to be difficult.


  • bomberboy
  • Registratie: Mei 2007
  • Laatst online: 17-11 23:44

bomberboy

BOEM!

Een stomme vraag misschien, maar die uitvoeringstijden, is dat de totale uitvoeringstijd van alles samen (dus het starten van alles centraal, dan alles uitsturen, alles terugkrijgen en weer samenvoegen?) Of zijn dit andere tijden (bv. tijd gespendeerd per node?)

Hoe worden de jobs in stukjes verdeeld? Wordt alles centraal in stukjes gekapt? Of in het geval van twee threads op één node, wordt dit dan op de node gedaan?

Wat betreft de eigenlijke nodes, zijn ze allemaal even snel? :) Welk OS en welke JVM draaien ze? Ik heb het nog al gezien dat bij bepaalde configuraties met één JVM op een multi-processor of multi-core machine de totale belasting niet tot 100% te krijgen was (Dit was wel in combinatie met allerlei applicatieservers).

Wat is trouwens de belangrijkste resource die je gebruikt: diskio, memory, netwerk, processing? Iets anders, combinatie? Aangezien twee threads op 1 node niet dubbel zo snel zijn als 1 thread op twee nodes zou ik vermoeden dat er wel een shared resource tussen zit waar je threads om vechten.

Hou er ook rekening mee dat je bij RMI met een deels gedistribueerde garbage collection zit met mogelijks iets langere (en niet triviaal te ontdekken) locks ertussen. (Maar afgaande op de heel korte duur van je testen is dat misschien niet het probleem)

Maar zoals flowerp al aangaf heb je meer info nodig ivm met de eigenlijke locks die er zijn en ook handig is de eigenlijke cpu/memory-belasting van alle machines.

  • justice strike
  • Registratie: Juni 2001
  • Laatst online: 17-11 18:23
flowerp schreef op maandag 21 januari 2008 @ 21:53:
[...]


Hmmm, je ziet wel dat de speed-up per node toevoegen voor elke type belasting (1 thread vs 2 threads per node) eigenlijk nog niet eens zo dramatisch is:

speedup 1thread/nodespeedup 2threads/nodespeedup1 vs speedup2
1->2 nodes1.67 1.601.04
2->4 nodes1.52 1.311.16
4->8 nodes1.23 1.061.16
Dat klopt, dat heeft met het iteratieve gedeelte van het algoritme te maken. Alle workers moeten op een gegeven moment wachten totdat de laatste job van de iteration uitgevoerd is. Ik heb overigens wat van de job generation weten af te schaven, per saldo heb ik de excecutiontime in tweeen gehakt. Maar het verschil tussen thread speedup en node speedup is nog steeds aanwezig.

nodes1 thread/node2 threads/node
1 node44.76830.175
2 nodes 22.723 16.731
4 nodes12.469 10.753
8 nodes8.352 7.849


maar het blijft frapant dat threads minder efficient werken dan rmi. dit is iets wat buiten verwachting blijft. vooral het dramatische verschil tussen 2 threads en 2 nodes 1 thread is frapant.
In beide gevallen, of je 1 thread per node gebruikt of 2 threads per node, neemt de speedup relatief gezien af. Als je van 2 naar 4 nodes gaat en daarna van 4 naar 8 nodes, is de relatieve speedup tussen de gevallen met 1 en 2 threads ondeling zelfs identiek 1.16.

Een andere aardige constante die opvalt is het delta tijd verschil tussen een zelfde aantal threads over een steeds groter aantal nodes:

2 threads: 1x2 vs 2x1 = 7.771s ~ 8 sec
4 threads: 2x2 vs 4x1 = 3.982s ~ 4 sec
8 threads: 4x2 vs 8x1 = 2.0922 ~ 2 sec
dit zou nu niet meer op gaan denk ik. nu is de implementatie minder efficient bij weinig nodes*threads en efficienter bij meerdere nodes*threads omdat ik in het begin meer jobs aanmaak bij bounds die relatief veel tijd in beslag nemen. Dit brengt uiteraard overhead met zich mee, maar de overhead is over veel nodes te verwaarlozen.

U can call me sir.... or justice as long as u bow down ;)


  • justice strike
  • Registratie: Juni 2001
  • Laatst online: 17-11 18:23
bomberboy schreef op dinsdag 22 januari 2008 @ 13:59:
Een stomme vraag misschien, maar die uitvoeringstijden, is dat de totale uitvoeringstijd van alles samen (dus het starten van alles centraal, dan alles uitsturen, alles terugkrijgen en weer samenvoegen?) Of zijn dit andere tijden (bv. tijd gespendeerd per node?)
uitvoeringstijd is totale uitvoeringstijd nadat alles is geinitialiseerd. Workers zijn al aangemaakt, connecties zijn al gemaakt maar jobs zijn nog niet gegenereeert.
Hoe worden de jobs in stukjes verdeeld? Wordt alles centraal in stukjes gekapt? Of in het geval van twee threads op één node, wordt dit dan op de node gedaan?
alles word centraal gegenereert.
Wat betreft de eigenlijke nodes, zijn ze allemaal even snel? :) Welk OS en welke JVM draaien ze? Ik heb het nog al gezien dat bij bepaalde configuraties met één JVM op een multi-processor of multi-core machine de totale belasting niet tot 100% te krijgen was (Dit was wel in combinatie met allerlei applicatieservers).
nodes zijn allemaal even langzaam (pentium 2 dacht ik?) draaien linux. jvm is 1.5 (weet ik bijna zeker). De cluster is ingericht voor gedistribueerde applicaties. Nodes zijn volledig te belasten. Sterker nog voor het runnen van een applicatie worden de nodes gereserveerd. Er draait niets anders op die node dan de applicatie jvm en de os op het moment van runnen.
Wat is trouwens de belangrijkste resource die je gebruikt: diskio, memory, netwerk, processing? Iets anders, combinatie? Aangezien twee threads op 1 node niet dubbel zo snel zijn als 1 thread op twee nodes zou ik vermoeden dat er wel een shared resource tussen zit waar je threads om vechten.
belangrijkste resources zijn memory processor en network. Disk wordt niet gebruikt. Het betreft overigens een smp systeem geen multicore. (ken geen multicore p2 ;)) Op mijn dualcore laptop haal ik meer efficientie dan op de smp systemen, zal wel latency zijn, maar ik verwacht eigenlijk niet dat dit een probleem moet zijn als rmi ook nog een rol speelt (rmi connecties duren veel langer dan de latency tussen cpu en memory)
Hou er ook rekening mee dat je bij RMI met een deels gedistribueerde garbage collection zit met mogelijks iets langere (en niet triviaal te ontdekken) locks ertussen. (Maar afgaande op de heel korte duur van je testen is dat misschien niet het probleem)
Is dat te checken?
Maar zoals flowerp al aangaf heb je meer info nodig ivm met de eigenlijke locks die er zijn en ook handig is de eigenlijke cpu/memory-belasting van alle machines.
ik ben bezig om dat na te gaan. Maar ik hebn al wat efficientie kunnen halen uit het tweaken van delen van mijn programma. Echter blijft het verschil threads vs nodes bestaan. I denk dat er niets anders op zit dan profilen.

U can call me sir.... or justice as long as u bow down ;)


  • bomberboy
  • Registratie: Mei 2007
  • Laatst online: 17-11 23:44

bomberboy

BOEM!

justice strike schreef op dinsdag 22 januari 2008 @ 15:08:
[...]
uitvoeringstijd is totale uitvoeringstijd nadat alles is geinitialiseerd. Workers zijn al aangemaakt, connecties zijn al gemaakt maar jobs zijn nog niet gegenereeert.
Aha. Dus er van uitgaande dat je opsplitsing van de data over meerdere threads een lineaire speedup betekent in het aantal threads(Dit is toch zo volgens het algoritme dat je gebruikt he?) Meet je dus eigenlijk enkel de overhead van het distribueren enzo. Het genereren van de jobs uit de tijdsmeting halen zou ook wel interessant kunnen zijn, of je moet kunnen garanderen dat het genereren van 1 job net even lang duurt als het genereren van n jobs. (met n>1)
Wordt er op het einde nog iets met die resultaten gedaan? (binnen het interval van de tijdsmeting) Het samenvoegen van 2 deelresultaten zou wel eens sneller klaar kunen zijn dan het samenvoegen van 16 (kleinere) deelresultaten.
nodes zijn allemaal even langzaam (pentium 2 dacht ik?) draaien linux. jvm is 1.5 (weet ik bijna zeker). De cluster is ingericht voor gedistribueerde applicaties. Nodes zijn volledig te belasten. Sterker nog voor het runnen van een applicatie worden de nodes gereserveerd. Er draait niets anders op die node dan de applicatie jvm en de os op het moment van runnen.
De eigenlijke kernel en het gebruik van linuxthreads of de native posix thread library en de eigenlijke JVM kunnen enorme verschillen maken. Maar laten we er van uitgaan dat alle machines identiek zijn, dan is dat op zich allemaal geen probleem. (in theorie althans :))
belangrijkste resources zijn memory processor en network. Disk wordt niet gebruikt. Het betreft overigens een smp systeem geen multicore. (ken geen multicore p2 ;)) Op mijn dualcore laptop haal ik meer efficientie dan op de smp systemen, zal wel latency zijn, maar ik verwacht eigenlijk niet dat dit een probleem moet zijn als rmi ook nog een rol speelt (rmi connecties duren veel langer dan de latency tussen cpu en memory)
Je kan eventueel eens proberen om alles via rmi te doen, maar dan op één fysieke machine en die resultaten te vergelijken. Maar dat is vooral een heel gedoe qua configuratie, maar kan zeker één en ander verduidelijken.
[distributed gc]
Is dat te checken?
Via profiling :)
Bij het opstarten van de JVM kan je het gc-interval voor rmi-toestanden meegeven aan de hand van volgende parameters:
-Dsun.rmi.dgc.server.gcInterval en -Dsun.rmi.dgc.client.gcInterval. Althans voor de SUn JVM. Maar als ik het me goed herinner is de default-waarde 60 seconden en is dit niet noodzakelijk een probleem. Mogelijks wordt die gc wel telkens aangeroepen bij het afsluiten van al je jobs, en veroorzaakt dit dus meer overhead naarmate er meer nodes zijn. Maar dat kan ik nu niet zo maar met zekerheid zeggen.
ik ben bezig om dat na te gaan. Maar ik hebn al wat efficientie kunnen halen uit het tweaken van delen van mijn programma. Echter blijft het verschil threads vs nodes bestaan. I denk dat er niets anders op zit dan profilen.
Het optimaliseren van delen van je algorithme ofzo gaat de eigenlijke bottlenecks doorgaans niet oplossen he. Dus ergens is dat wel logisch.

Maar als ik het goed begrijp is hetgene wat je echt aan het meten bent momenteel de uitvoeringstijd van de traagste node + de tijd nodig om alles op te zetten en af te breken.
En afgaande op het meeste dat ik tot nu toe al gelezen hebt wordt een significant deel van de tijd gespendeerd in het opzetten van alles. Andere testen die je kan doen is net hetzelfde van wat je nu gedaan hebt, maar de nodes geen rekenwerk te laten doen maar er gewoon een sleep in te stoppen en die tijd te variëren. Dan meet je enkel de extra overhead. ipv rekenwerk, laat alle nodes gewoon 10s slapen, onafhankelijk van hoeveel nodes en threads, variëer hierbij het aantal nodes en threads en eventueel die tijd.
Doe hetzelfde maar dan met de grootte van de objecten die je doorstuurt met je workers en eventueel de resultaten enz.

Dan weet je op zijn minst al of het probleem ergens in de overhead zit of niet.

  • justice strike
  • Registratie: Juni 2001
  • Laatst online: 17-11 18:23
bomberboy schreef op dinsdag 22 januari 2008 @ 16:03:
[...]


Aha. Dus er van uitgaande dat je opsplitsing van de data over meerdere threads een lineaire speedup betekent in het aantal threads(Dit is toch zo volgens het algoritme dat je gebruikt he?) Meet je dus eigenlijk enkel de overhead van het distribueren enzo. Het genereren van de jobs uit de tijdsmeting halen zou ook wel interessant kunnen zijn, of je moet kunnen garanderen dat het genereren van 1 job net even lang duurt als het genereren van n jobs. (met n>1)
Wordt er op het einde nog iets met die resultaten gedaan? (binnen het interval van de tijdsmeting) Het samenvoegen van 2 deelresultaten zou wel eens sneller klaar kunen zijn dan het samenvoegen van 16 (kleinere) deelresultaten.
Nee er word niets met het resultaat gedaan binnen de tijdsmeting. De job generation ertussenuit halen is lastig omdat je namelijk met bounds zit en dus dus zal de node
tussende bounds door jobs genereren.
[...]

Je kan eventueel eens proberen om alles via rmi te doen, maar dan op één fysieke machine en die resultaten te vergelijken. Maar dat is vooral een heel gedoe qua configuratie, maar kan zeker één en ander verduidelijken.
alles gebeurt via rmi. threads maken rmi calls naar queue. Zelfs als ze op dezelfde machine zitten (althans zo had ik dat eerst met de eerste tabel die ik liet zien, dat heb ik onderhand verandert omdat dat eigenlijk a waste of resources is)
Maar als ik het goed begrijp is hetgene wat je echt aan het meten bent momenteel de uitvoeringstijd van de traagste node + de tijd nodig om alles op te zetten en af te breken.
nee ik meet enkel en alleen de excecutietijd (incluis jobgeneration aangezien dat inherent is aan het algoritme) Opbouwen en afbreken wordt niet meegenomen in de tijd.

Ik heb net een ingeving gehad. Ik zet nu de threads op met behulp van een constructor die een queue object meegeeft. Dit object is een object wat door de getregistry functie wordt geretourneerd (als ik mij niet vergis).

zou het kunnen zijn dat omdat ik per 2 threads de reference naar hetzelfde (remote) object geef dat het langzamer is? misschien moet ik 2 references aanmaken naar dezelfde remote object(wat eigenlijk wel vreemd is omdat jvm toch een pool van connecties bijhoud). Ik ga het zo even proberen.


helaas heeft het ook niet te maken met 2 threads die een reference hebben naar hetzelfde (remote) object

U can call me sir.... or justice as long as u bow down ;)


  • justice strike
  • Registratie: Juni 2001
  • Laatst online: 17-11 18:23
ik ga nog een keer proberen alles een beetje duidelijk uit te leggen. Ik ben soms wat onduidelijk en dat merk ik in de reacties van iedereen.

het programma begint met de initialisatie
-master node :
1.maakt een queue aan, bind deze aan de registry
2. vervolgens maakt de master node 1 of 2 worker threads aan welke een referentie krijgen naar de queue (lokaal, dit was eerst via rmi).
3. jobs worden gegenereert en in de queue gestopt, zodra er jobs in de queue zitten kunnen de workers beginnen met werken.
4. is de queue leeg dan betekent het dat de bound afgelopen is. er wordt gekeken in de queue of er een antwoord is, mocht dat niet zo zijn dan worden er nieuwe jobs in de queue gezet voor de volgende bound.
5. is het antwoord wel gevonden stuurd de master node een signaaltje dat de applicatie gaat afsluiten en print het antwoord op het scherm waarna alles

slave node:
-slave nodes halen een reference van de queue op uit de registry en maken hiermee een remote object aan. Deze maakt vervolgens 1 of 2 worker threads aan die de reference krijgen van deze remote object.
-master thread (niet node) gaat slapen, polled enkel elke seconde of de applicatie al gestopt is waarna hij de applicatie afsluit.

queue:
-accepteerd jobs van de masterthread en retourneert jobs aan de workerthreads
-accepteerd antwoorden van workerthreads
-als er geen job is dan locked the queue the worker totdat er een job binnenkomt. Dit werkt naar behoren, geen deadlocks oid.

worker:
-haalt werk op uit de queue verwerkt deze mocht er een antwoord uit komen dan wordt deze geretourneerd naar de queue.

hopelijk maakt dit alls een beetje duidelijk. Aangezien elke thread dus een reference krijgt naar het remote object zou alles theoretisch via rmi moeten gaan.

[ Voor 3% gewijzigd door justice strike op 22-01-2008 16:54 ]

U can call me sir.... or justice as long as u bow down ;)


  • bomberboy
  • Registratie: Mei 2007
  • Laatst online: 17-11 23:44

bomberboy

BOEM!

Dat verduidelijkt (voor mij) toch al één en ander :) Ik was onder de indruk dat je je begindata gewoon in x gelijke stukken kon opsplitsen en er dan zo eentje per thread had dat dan afzonderlijk verwerkt wordt. Maar dat klopte niet helemaal blijkbaar aangezien alle taakjes gaan ophalen, verwerken en dan antwoorden terugsturen?
En die verschillende jobs zijn verschillend in complexiteit en dus duur nodig voor de verwerking?

Dus een verdubbeling van het aantal nodes en/of threads zal niet noodzakelijk een halvering van de rekentijd bedragen in dat geval. (Want daar was ik ook wat naar op zoek.)

Begrijp ik het zo goed?

En die master thread die je vermeldt bij de queue, dat is er eentje op de master node, of anders snap ik de link met die op de slave node toch niet helemaal.

Tot slot mag of kan je er ook niet altijd van uitgaan dat 2 threads op een dualcore machine even snel zal zijn als 2 dual core machines met elk één thread. (Er zijn altijd wel andere dingen die in de achtergrond nog gebeuren). Overigens is het verschil in uitvoeringstijd tussen de 1-thread versie en 2-thread versie wel (4 nodes 1 thread vs 2 nodes 2 threads enz.) procentueel wel ongeveer gelijk (rond de 30%).

Zeker indien die machines met een iets oudere linux-kernel zijn uitgerust kan dit een verklaring zijn. (scheduling op smp systemen is niet altijd even performant geweest, zeker niet bij zware belasting)

  • justice strike
  • Registratie: Juni 2001
  • Laatst online: 17-11 18:23
bomberboy schreef op dinsdag 22 januari 2008 @ 18:37:
Dat verduidelijkt (voor mij) toch al één en ander :) Ik was onder de indruk dat je je begindata gewoon in x gelijke stukken kon opsplitsen en er dan zo eentje per thread had dat dan afzonderlijk verwerkt wordt. Maar dat klopte niet helemaal blijkbaar aangezien alle taakjes gaan ophalen, verwerken en dan antwoorden terugsturen?
En die verschillende jobs zijn verschillend in complexiteit en dus duur nodig voor de verwerking?
Het is eigenlijk een zoek algoritme. (iterative deepening A*). Je doorzoekt een boom. De jobs zijn de eerste paar nodes binnen die boom (haal deze nodes aub niet door de war met de machine nodes). idd heeft elke job een andere complexiteit. Maar als je maar genoeg jobs genereert (dus genoeg nodes binnen de zoekboom genereert) zorg je dat dat steeds beter verdeelt wordt tussen de threads.
Echter speelt hier weer de afweging, hoeveel jobs ga ik genereren. Want als het genereren van jobs langer duurt dan het uitrekenen dan verlies je daar weer tijd op.
Dus een verdubbeling van het aantal nodes en/of threads zal niet noodzakelijk een halvering van de rekentijd bedragen in dat geval. (Want daar was ik ook wat naar op zoek.) Begrijp ik het zo goed?
klopt idd, het is de afweging die je maakt tussen genereren van jobs (hoe meer je genereert hoe finer grained het wordt) en de rekentijd. Maar dit heeft ansich weinig te maken met het probleem wat ik ondervind.
En die master thread die je vermeldt bij de queue, dat is er eentje op de master node, of anders snap ik de link met die op de slave node toch niet helemaal.
idd bedoelde ik daar de master thread op de master node die alle jobs genereert. (theoretisch zou ik ook workers jobs kunnen laten genereren maar dat zou dan vele malen complexer worden en er zou veel meer network io zijn waardoor ik de kans klein acht dat het sneller zou zijn)
Tot slot mag of kan je er ook niet altijd van uitgaan dat 2 threads op een dualcore machine even snel zal zijn als 2 dual core machines met elk één thread. (Er zijn altijd wel andere dingen die in de achtergrond nog gebeuren). Overigens is het verschil in uitvoeringstijd tussen de 1-thread versie en 2-thread versie wel (4 nodes 1 thread vs 2 nodes 2 threads enz.) procentueel wel ongeveer gelijk (rond de 30%).
ansich zou je verwachten dat 2 threaded versies efficienter zouden zijn. je hebt namelijk per thread minder overhead.

single threaded versie per 1 thread overhead: os, jvm, garbage collector, memory allocation etc..
dual threaded versie per 1 thread overhead: 1/2os, 1/2 jvm, 1/2 garbage collector, memory allocation etc..

Gaat niet helemaal op aangezien je met een single threaded versie nog 1 processor over hebt die nog het een en ander kan doen. maar ik zie niet in waarom ik die 30% overhead zou hebben met threading tov een extra node. (overigens is 30% overhead wel erg veel :S)
Zeker indien die machines met een iets oudere linux-kernel zijn uitgerust kan dit een verklaring zijn. (scheduling op smp systemen is niet altijd even performant geweest, zeker niet bij zware belasting)
geen idee welke versie het is. Het zal waarschijnlijk wel een peformance implementatie zijn. De cluster is vroeger gebruikt om zware wetenschappelijke berekeningen op uit te voeren.

U can call me sir.... or justice as long as u bow down ;)


  • bomberboy
  • Registratie: Mei 2007
  • Laatst online: 17-11 23:44

bomberboy

BOEM!

Ok, ik denk dat ik nu helemaal mee ben met het probleem :)
Voorlopig geen oplossing, maar wel nog een paar opmerkingen :
justice strike schreef op dinsdag 22 januari 2008 @ 19:11:
ansich zou je verwachten dat 2 threaded versies efficienter zouden zijn. je hebt namelijk per thread minder overhead.

single threaded versie per 1 thread overhead: os, jvm, garbage collector, memory allocation etc..
dual threaded versie per 1 thread overhead: 1/2os, 1/2 jvm, 1/2 garbage collector, memory allocation etc..
Indien die twee threads totaal onafhankelijk van elkaar zijn, maar wel in dezelfde JVM draaien kan dit bijna enkel minder efficiënt zijn (op een wat lager geheugengebruik na)

De overhead van je OS blijft hetzelfde, misschien wordt die wel wat groter bij meerdere threads omdat de JVM sneller en vaker zal aankloppen om meer resources te krijgen en allerhande interrupts genereren.

Voor de JVM wordt het ook complexer omdat deze zelf een eigen scheduler heeft die ook nog eens 2 threads moet managen. Twee heel intensieve threads dan nog wel. En zeker op een wat oudere linux-kernel waar er toch wel wat quirks kunnen zijn met Java op Linux. In het andere geval heb je eigenlijk maar één thread die quasi alle resources kan krijgen wat voor twee threads niet altijd het geval zal zijn omdat het proces van je JVM niet continue beide cpu's zal mogen opslokken. (ééntje 100% belasten zal in praktijk altijd wel lukken beiden 100% met nuttige bewerkingen is al iets minder waarschijnlijk)

De garbage collection zal in het geval van 2 threads ook veel meer werk krijgen dan in het geval van 1 thread. Er zijn immers twee threads die mogelijks objecten aanmaken en terug vrijgeven enz. (Is uiteraard sterk afhankelijk van je implementatie over hoeveel er dat zijn, maar het is vaak meer dan je denkt). Bovendien heeft je JVM evenveel geheugen tot zijn beschiking ongeacht het aantal threads dat er binnen draait, bijgevolg moet de garbage collection misschien veel vaker in werking schieten omdat dit geheugen vol zit. Op SMP en multicore systemen zal de garbage collection trouwens meerdere threads starten, en indien dan 1 cpu helemaal vrij is kan deze sneller gaan dan wanneer deze ook nog eens met een processingthread moet gaan strijden om resources..

Ik geef toe dat 30% misschien wel veel is of lijkt maar in een worst case scenario waar je met twee threads eigenlijk net te weinig geheugen hebt en met 1 de garbage collection nauwelijks moet werken (en dit voor een groot deel nog eens parallel kan doen) is dat ook weer niet onmogelijk.

Maar afgaande op de info van je probleem lijkt het me nu op het eerste zicht niet zo waarschijnlijk dat dit ook echt gebeurt in jouw geval.
geen idee welke versie het is. Het zal waarschijnlijk wel een peformance implementatie zijn. De cluster is vroeger gebruikt om zware wetenschappelijke berekeningen op uit te voeren.
Vroeger is lang geleden ;) Java en Linux hebben een vreemde geschiedenis samen wat performance dingen betreft met soms vreemde resultaten. En ik heb ook al zeer slecht performerende scientific linux bakken gezien (voor java), trust me :). (Wil uiteraard niet zeggen dat dit hier ook het geval is)

Maar ik vrees dat je toch eens zal moeten proberen om je applicatie of een deel ervan door een profiler te jagen. Het gaat anders heel moeilijk worden om echt te achterhalen wat het probleem is, en of je er zelf wel iets kan aan verbeteren.

  • justice strike
  • Registratie: Juni 2001
  • Laatst online: 17-11 18:23
ok ik heb eindelijk een profile kunnen runnen. Ik ga ze even uploaden ergens zodat jullie ze eventueel in kunnen zien. Hprof wordt een beetje voor de gek gehouden door de network stack, hij laat zien dat 50% van de cpu wordt gespendeerd aan accepting sockets. Ik heb het even opgezocht, maar dit schijnt een foutje te zijn, het zijn blocking calls, dus hij zou ondertussen toch verder gaan met rekenen.

als ik het goed lees neemt het uitrekenen van de oplossing toch het gros van de tijd in (makemoves() is het daadwerkelijke uitrekenen, deze wordt weer aangeroepen in solutions())

1 node 2 threads

2 node 2 threads

2 node 2 threads

[ Voor 6% gewijzigd door justice strike op 25-01-2008 01:33 ]

U can call me sir.... or justice as long as u bow down ;)


  • Jaap-Jan
  • Registratie: Februari 2001
  • Laatst online: 20-11 18:44
Ik krijg een 404 op beide bestanden en de map ~pfk300.

| Last.fm | "Mr Bent liked counting. You could trust numbers, except perhaps for pi, but he was working on that in his spare time and it was bound to give in sooner or later." -Terry Pratchett


  • justice strike
  • Registratie: Juni 2001
  • Laatst online: 17-11 18:23
ik zag het net zelf ook. Bij deze opgelost :)

overigens zijn de profiles redelijk stabiel. heb namelijk een aantal keren de programmas gerunned en er komen nagenoeg dezelfde percentages uit

[ Voor 122% gewijzigd door justice strike op 25-01-2008 01:34 ]

U can call me sir.... or justice as long as u bow down ;)


  • justice strike
  • Registratie: Juni 2001
  • Laatst online: 17-11 18:23
ik begin me nu toch af te vragen of die 50% cpu usages niet enige kern van waarheid hebben. Ik zie namelijk niet in waar mijn cpu power anders naartoe gaat.

U can call me sir.... or justice as long as u bow down ;)


  • bomberboy
  • Registratie: Mei 2007
  • Laatst online: 17-11 23:44

bomberboy

BOEM!

Heb je er ondertussen al iets meer van kunnen maken? Want ik ben eigenlijk ook wel nieuwsgierig naar wat het probleem juist is. En een beetje wantrouwig naar de resultaten van die hprof en socket.

Maar met welke argumenten heb je die hprof net uitgevoerd? Want ik vind niet zo direct info over het gebruik van de heap terug in die logfiles? Ik weet wel dat je dat kan aanzetten (zeker voor het binaire outputformaat). Die binaire output kan je dan analyseren met jhat dat normaal bij je JVM zit. En ook de meeste commerciële profilers kunnen dat formaat lezen en analyseren (JProfiler, YourKit...)

  • justice strike
  • Registratie: Juni 2001
  • Laatst online: 17-11 18:23
double

[ Voor 99% gewijzigd door justice strike op 29-01-2008 16:16 ]

U can call me sir.... or justice as long as u bow down ;)


  • justice strike
  • Registratie: Juni 2001
  • Laatst online: 17-11 18:23
bomberboy schreef op dinsdag 29 januari 2008 @ 11:13:
Heb je er ondertussen al iets meer van kunnen maken? Want ik ben eigenlijk ook wel nieuwsgierig naar wat het probleem juist is. En een beetje wantrouwig naar de resultaten van die hprof en socket.

Maar met welke argumenten heb je die hprof net uitgevoerd? Want ik vind niet zo direct info over het gebruik van de heap terug in die logfiles? Ik weet wel dat je dat kan aanzetten (zeker voor het binaire outputformaat). Die binaire output kan je dan analyseren met jhat dat normaal bij je JVM zit. En ook de meeste commerciële profilers kunnen dat formaat lezen en analyseren (JProfiler, YourKit...)
Ik ben er nog steeds niet uit. Ben op andere plekken tweaks aan het uitvoeren. Maar waar het probleem nou werkelijk zit kan ik niet zeggen. Het vreemde is dat de peformance theoretisch wel hetzelfde zou kunnen zijn. Ik krijg namelijk bij het doen van een testrun (5 keer achter elkaar draaien) sporadisch peformance metingen die voor 2 threads op 1 node gelijk zijn aan 2 nodes 1 thread.


volgens mij heb ik voor hprof deze arguments gebruikt: "-Xrunhprof:heap=sites,cpu=samples,depth=10,monitor=y,thread=y,doe=y"
geen idee meer welke settings ik gebruikt heb, de settings hierboven werken in iedergeval niet.

(weet het niet zeker omdat de configurations in een ander bestand staan, welke ik weer veranderd heb.) Misschien kunnen jullie mij aangeven welke opties ik het beste kan aanzetten.

[ Voor 7% gewijzigd door justice strike op 29-01-2008 16:57 ]

U can call me sir.... or justice as long as u bow down ;)

Pagina: 1