Toon posts:

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

Pagina: 1
Acties:

Onderwerpen


  • Umbrah
  • Registratie: Mei 2006
  • Laatst online: 22:42

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

  • RobIII
  • Registratie: December 2001
  • Laatst online: 03:54

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

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.

Roses are red Violets are blue, Unexpected ‘{‘ on line 32.

Over mij


  • Umbrah
  • Registratie: Mei 2006
  • Laatst online: 22:42

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.

  • RobIII
  • Registratie: December 2001
  • Laatst online: 03:54

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

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.

Roses are red Violets are blue, Unexpected ‘{‘ on line 32.

Over mij


  • Umbrah
  • Registratie: Mei 2006
  • Laatst online: 22:42

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]



Tweakers maakt gebruik van cookies

Tweakers plaatst functionele en analytische cookies voor het functioneren van de website en het verbeteren van de website-ervaring. Deze cookies zijn noodzakelijk. Om op Tweakers relevantere advertenties te tonen en om ingesloten content van derden te tonen (bijvoorbeeld video's), vragen we je toestemming. Via ingesloten content kunnen derde partijen diensten leveren en verbeteren, bezoekersstatistieken bijhouden, gepersonaliseerde content tonen, gerichte advertenties tonen en gebruikersprofielen opbouwen. Hiervoor worden apparaatgegevens, IP-adres, geolocatie en surfgedrag vastgelegd.

Meer informatie vind je in ons cookiebeleid.

Sluiten

Toestemming beheren

Hieronder kun je per doeleinde of partij toestemming geven of intrekken. Meer informatie vind je in ons cookiebeleid.

Functioneel en analytisch

Deze cookies zijn noodzakelijk voor het functioneren van de website en het verbeteren van de website-ervaring. Klik op het informatie-icoon voor meer informatie. Meer details

janee

    Relevantere advertenties

    Dit beperkt het aantal keer dat dezelfde advertentie getoond wordt (frequency capping) en maakt het mogelijk om binnen Tweakers contextuele advertenties te tonen op basis van pagina's die je hebt bezocht. Meer details

    Tweakers genereert een willekeurige unieke code als identifier. Deze data wordt niet gedeeld met adverteerders of andere derde partijen en je kunt niet buiten Tweakers gevolgd worden. Indien je bent ingelogd, wordt deze identifier gekoppeld aan je account. Indien je niet bent ingelogd, wordt deze identifier gekoppeld aan je sessie die maximaal 4 maanden actief blijft. Je kunt deze toestemming te allen tijde intrekken.

    Ingesloten content van derden

    Deze cookies kunnen door derde partijen geplaatst worden via ingesloten content. Klik op het informatie-icoon voor meer informatie over de verwerkingsdoeleinden. Meer details

    janee