Geachte Heren en Dames,
De afgelopen weken ben ik voor een klant bezig geweest met een onderzoek naar rekenbibliotheken en precisie. Een succesvolle presentatie later vonden ze dat ik goed werk had geleverd in het afleveren van een applicatie die puur en alleen rekenbibliotheken test aan de hand van een proef gegevensset van dit bedrijf. Single processing, dat is, tenminste.
Een omschrijving van mijn proef pakketje:
Een portable binary (Linux, Windows, 32 en 64 bit) geschreven in C en C++ die afhankelijk is van een proprieatary rekenklasse van 15 jaar oud en op het moment: MPIR (een fork van GMP). Dit programma wordt eigenlijk getest door middel van puur en alleen de runtime, met vier parameters. Dit zijn puur en alleen nummers. De parameters zijn als volgt:
Een voorbeeld van de output hiervan:
Het programma is afhankelijk van een hardcoded datafile die in dezelfde directory staat. Hierdoor is de working directory van belang.
Dit werkt allemaal, en het werkt allemaal goed, maar het probleem is: ik moet nu schalen. 40 fysieke cores in één machine en los van OS keuze: er moet mee getest worden. Ik wil dus het starten van deze programma's automatiseren en logtextfiles aanmaken. Gezien het feit dat er nu primair Windows wordt gebruikt, zal ik daar ook onder testen. Tot dit doel ben ik een simpel "launchertje" aan het maken.
Doel: instellen hoeveel sessies, executable aanwijzen, codepath aanwijzen, en op start drukken.
Dit werkt ook, en dat is heel simpel. Het tweede doel is: output! Ik wil die mooie uitvoer hierboven graag in losse tekstbestanden hebben. En daar zit hem de crux: een lussend proces zal via redirects (programma > output.txt) nooit iets wegschrijven, zodra ik op "CTRL+C" druk heb ik een lege textfile.
Ik heb lang gezocht, maar nog geen manier gevonden:
• BAT file genereren die de executable start met een redirect > werkt niet
• Powershell en " | out-file filename.txt" werkt niet, zelfs niet met gegenereerde .PS1 scripts
• ProcessStartInfo bied de eigenschappen "redirectstandardoutput" naar een streamreader, dit klinkt ideaal maar gezien het lussend karakter regelt dit alleen maar een freeze. Wat voor Streamwriter, backgroundprocesshandler die naar de UI Print of andere ongein ik er ook tussen zet.
Ik kan me haast niet voorstellen dat ik de enige ben met dit probleem, maar na lang zoeken ben ik nog niks verder.
Ik ben nu zover dat dit VB script elk getal aan processen ongeveer tegelijk start; of het er nu 1 is of 40 zijn, en het is zelf eigenlijk niet zwaar: ik heb indien ik de redirectstandardoutput op false heb en useshellexecute op true (zodat ik kan zien wat het doet) géén performanceloss. Het OS zorgt er keurig voor dat elke start zijn eigen CPU krijgt die vervolgens vanwege de lus vol op de 100% schiet en blijft: hij maakt keurig zijn berekeningen. Tot zover een ideaal script, ik wens alleen de outputs van elk proces in een textfile te hebben.
bestandnaam - nummertje - .txt. Dit moet gebeuren zonder aanpassing van het C-programma, dus ergens moet ik de prints naar console direct wegschrijven. En dat mag niet te duur zijn.
Hoe los ik dit op?
De relevante code tot zo ver:
De afgelopen weken ben ik voor een klant bezig geweest met een onderzoek naar rekenbibliotheken en precisie. Een succesvolle presentatie later vonden ze dat ik goed werk had geleverd in het afleveren van een applicatie die puur en alleen rekenbibliotheken test aan de hand van een proef gegevensset van dit bedrijf. Single processing, dat is, tenminste.
Een omschrijving van mijn proef pakketje:
Een portable binary (Linux, Windows, 32 en 64 bit) geschreven in C en C++ die afhankelijk is van een proprieatary rekenklasse van 15 jaar oud en op het moment: MPIR (een fork van GMP). Dit programma wordt eigenlijk getest door middel van puur en alleen de runtime, met vier parameters. Dit zijn puur en alleen nummers. De parameters zijn als volgt:
- Codepath (1 = MPIR-C, 2 = De 15 jaar oude classe, 3 = MPIR-C++, 4= Long Double, 0 = none, geen berekeningen maar alleen timers voor referentie
- Output (1 = alle sommen worden weergegeven, 0 = geen sommen worden weergegeven maar alleen de timer-uitvoer)
- Perpetual (0 = de test gaat maar één keer; 1 = de test gaat oneindig door totdat er een break (CTRL+C) wordt gegeven)
- Totaalweergave (0 = laat alle timers zien in een ascii-tabelletje, timer per type berekening, dat soort zut. 1 = Laat alleen de totaal tijd zien zonder enige vorm van formatting, 2 = zelfde maar dan minus de tijd die het kost om de timers te berekenen).
./perftest.exe 3 0 1 2
Een voorbeeld van de output hiervan:
code:
1
2
3
4
5
| Nr of items in map: 2718560 2.325600 2.319465 2.324257 2.321807 |
Het programma is afhankelijk van een hardcoded datafile die in dezelfde directory staat. Hierdoor is de working directory van belang.
Dit werkt allemaal, en het werkt allemaal goed, maar het probleem is: ik moet nu schalen. 40 fysieke cores in één machine en los van OS keuze: er moet mee getest worden. Ik wil dus het starten van deze programma's automatiseren en logtextfiles aanmaken. Gezien het feit dat er nu primair Windows wordt gebruikt, zal ik daar ook onder testen. Tot dit doel ben ik een simpel "launchertje" aan het maken.
Doel: instellen hoeveel sessies, executable aanwijzen, codepath aanwijzen, en op start drukken.
Dit werkt ook, en dat is heel simpel. Het tweede doel is: output! Ik wil die mooie uitvoer hierboven graag in losse tekstbestanden hebben. En daar zit hem de crux: een lussend proces zal via redirects (programma > output.txt) nooit iets wegschrijven, zodra ik op "CTRL+C" druk heb ik een lege textfile.
Ik heb lang gezocht, maar nog geen manier gevonden:
• BAT file genereren die de executable start met een redirect > werkt niet
• Powershell en " | out-file filename.txt" werkt niet, zelfs niet met gegenereerde .PS1 scripts
• ProcessStartInfo bied de eigenschappen "redirectstandardoutput" naar een streamreader, dit klinkt ideaal maar gezien het lussend karakter regelt dit alleen maar een freeze. Wat voor Streamwriter, backgroundprocesshandler die naar de UI Print of andere ongein ik er ook tussen zet.
Ik kan me haast niet voorstellen dat ik de enige ben met dit probleem, maar na lang zoeken ben ik nog niks verder.
Ik ben nu zover dat dit VB script elk getal aan processen ongeveer tegelijk start; of het er nu 1 is of 40 zijn, en het is zelf eigenlijk niet zwaar: ik heb indien ik de redirectstandardoutput op false heb en useshellexecute op true (zodat ik kan zien wat het doet) géén performanceloss. Het OS zorgt er keurig voor dat elke start zijn eigen CPU krijgt die vervolgens vanwege de lus vol op de 100% schiet en blijft: hij maakt keurig zijn berekeningen. Tot zover een ideaal script, ik wens alleen de outputs van elk proces in een textfile te hebben.
bestandnaam - nummertje - .txt. Dit moet gebeuren zonder aanpassing van het C-programma, dus ergens moet ik de prints naar console direct wegschrijven. En dat mag niet te duur zijn.
Hoe los ik dit op?
De relevante code tot zo ver:
Visual Basic .NET:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
| cmdParams = NUDCodePath.Value.ToString & " 0 1 " 'Een numeric up down op het form die het codepath bepaald (0 t/m 4) If CHKWaste.Checked = True Then cmdParams = cmdParams & "1" 'waste registratie erbij of niet? Else cmdParams = cmdParams & "2" 'zie boven End If 'Dim sw As New System.IO.StreamWriter(txtRuntimePath.Text & ".bat", False) 'sw.WriteLine(txtRuntimePath.Text & cmdParams & " > outputfile%1.txt") 'sw.Close() cmdRuntime = txtRuntimePath.Text ' & ".bat" 'een openfiledialog vult deze textbox met de exe (nodig omdat ik meerdere compile versies heb) die nodig is ReDim processarray(NUDAmountOfThreads.Value - 1) 'yup, arrays. handig. Schaalbaar. For i = 0 To processarray.Length - 1 Dim procstarter As New ProcessStartInfo procstarter.FileName = cmdRuntime 'de runtime, zeg: perftest.exe procstarter.Arguments = cmdParams 'de parameters, zeg: 3 0 1 2 procstarter.RedirectStandardOutput = True procstarter.UseShellExecute = False procstarter.WorkingDirectory = cmdWorkDir 'de werkdirectory, zelfde pad waar de exe staat processarray(i) = Process.Start(procstarter) 'start hem als zijn deel van de array. Next |