[VB.Net] Output van meerdere programma's naar file

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Umbrah
  • Registratie: Mei 2006
  • Laatst online: 12:57

Umbrah

The Incredible MapMan

Topicstarter
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:
  • 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).
Een voorbeeld hoe dit programma gestart kan worden:
./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

Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Wat ik er van denk te begrijpen en vermoed dat er aan de hand is is dat de applicatie z'n output niet via stdOut stuurt. Hoe dat dan wél gebeurt weet ik niet, maar komt de output niet van, zeg, stdErr? In dat geval, wat overigens vreemd zou zijn maar je weet nooit, zou je RedirectStandardErr kunnen gebruiken kunnen gebruiken. Je kunt 't overigens makkelijk even testen in je shell door dit te bekijken.

[ Voor 21% gewijzigd door RobIII op 17-06-2011 14:01 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • Umbrah
  • Registratie: Mei 2006
  • Laatst online: 12:57

Umbrah

The Incredible MapMan

Topicstarter
Helaas, dit heeft me niet geholpen. Het C++ programma is in veel aspecten een eigenlijk C-programma, en heeft dan ook echt structuren als:

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
if ( strcmp( (iter->operand).c_str(), "(op*=)") == 0 
            || strcmp( (iter->operand).c_str(), "(op*)") == 0
            )
            {

                if (code_path==1)
                {
                    mpf_mul(cp1_res_lib, cp1_op_a,cp1_op_b);
                    if (output==1)
                    {
                        gmp_printf ("OPP MUL: %.*Ff", 8, cp1_op_a);
                        printf (" * ");
                        gmp_printf ("%.*Ff", 8, cp1_op_b);
                        printf (" = ");
                        gmp_printf ("%.*Ff \n", 8, cp1_res_lib);
                    }
                }


Ik heb een simpele import van STDIO.h toegevoegd en een "COUT hello world" aan elke optel functie (die zo'n 1,1 miljoen keer per run van het proces gaat), zodat ik zeker output heb, en als ik de output niet redirect zit mijn console helemaal vol. Zodra ik wát voor output dan ook ga redirecten, gaat het goed TOTDAT ik het programma zelf-herhalend laat werken, wat de bedoeling is. Als het programma neverending is (als in: hij herhaalt na het printen van de totaaltijd alle berekeningen nogmaals, de datafile wordt niet nogmaals ingelezen) krijg ik géén uitvoer van redirects, COUT, Printf, wat dan ook.

Vraag me niet waarom dit programma trouwens C en C++ combineert, ik heb het slechts afgemaakt en aangepast aan de hand van wat de opdrachtgever in elkaar had gezet.

Het programma doet wat het moet doen, en dat is puur rekenen. Ik wil het uitvoeren met output op 0 (geen uitkomsten), en herhalend op 1 (als in: het programma is nooit "klaar" maar zal 100% CPU blijven trekken van één core). Het probleem is en blijft die output in die situatie afvangen. Zonder herhalingen uitvoeren werkt wel.

Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Moet het niet iets als:
C:
1
gmp_printf(stdout, "foo");

zijn :? Ik roep maar effe wat, van the top of my head :P
Nope; gaat default naar stdout (as expected). Was maar een gokje :P

Het was me niet helemaal duidelijk dat je ook daadwerkelijk bij de broncode van die tool kon. Als dat zo is moet je iig al veel verder kunnen komen dan ik initieel dacht.

Is de output niet gewoon gebufferd en moet er niet een fflush() ofzo gedaan worden?

[ Voor 57% gewijzigd door RobIII op 17-06-2011 16:59 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • Umbrah
  • Registratie: Mei 2006
  • Laatst online: 12:57

Umbrah

The Incredible MapMan

Topicstarter
Noem me dom, maar ik heb hem opgelost, voorlopig tenminste:

Het zat hem d'r in er wel geschreven wordt, maar het bleef vrolijk in de cache hangen. Leuk. Gelukkig had ik de broncode en kon ik vóór de beslissing die bepaald of het programma z'n eeuwige lus vrolijk doorzet of stopt het volgende toevoegen:

C:
1
fflush(stdout);


Overigens: bij printf (en MPIR's gmp_printf) geen vermelding maken zorgt voor een automatische "stdout".

Ironie: jij kwam tegelijk met mij op de oplossing in je edit ;) Toch bedankt!

[ Voor 8% gewijzigd door Umbrah op 17-06-2011 17:09 ]