From: Ole-Hjalmar Kristensen on 3 Sep 2009 04:49 Just another thought: Would reading the string into a large enough buffer and just return a string descriptor (pointer and bounds) to the line be considered cheating? That way, you could avoid ever copying strings, just copy the whole of stdin to a large buffer and return the lines as descriptors. -- C++: The power, elegance and simplicity of a hand grenade.
From: Georg Bauhaus on 3 Sep 2009 06:39 Ole-Hjalmar Kristensen schrieb: >>>>>> "GB" == Georg Bauhaus <rm.tsoh.plus-bug.bauhaus(a)maps.futureapps.de> writes: > GB> It looks like copying In_Buf(Start..I-1) be circumvented. > GB> I have added a solution to Line_IO. > > How did you avoid the copying? Only in the non-recursive case, and only "inside" the subprogram, by renaming the slice in question and then either - create an overlay where some string object (of a subtype with the needed bounds) uses the renamed slice as storage. (Perhaps use Unchecked_Conversion if Randy's comments on Gem #39 suggest it.) Or, - convert said renamed slice to a string subtype with proper bounds. I'm still struggling (in spare free time) with long lines with or without terminators, proper End_Error (to mimick Text_IO.Get_Line's behavior), terminal I/O, and recursion. (An interesting test case (from a still open Python bug) is this: $ cat | ./line_reading_program asdf ^D $ ./line_reading_program asdf ^D
From: Olivier Scalbert on 3 Sep 2009 09:44 Georg Bauhaus wrote: > jonathan wrote: >> I forgot to add I used: >> >> gnatmake -gnatnp -O3 -funroll-all-loops -march=native knucleotide >> >> with a running time of (usually) 7.25 sec on the 25Meg data file: >> >> time ./knucleotide < fasta25.dat > > Thanks for running the program, glad to hear how they work. > > Meanwhile I have a tasking version which runs a little (25%) > faster. The two new changes are > > 1 - make 3 additional tasks call Write; round robin > > 2 - order the results using a protected Printer object > with entry families. Heck, these entry families have clever > features! :-) > > > http://home.arcor.de/bauhaus/Ada/knucleotide.tasking.gnat Hi, Same result for me ! One question: I have tried to profile knucleotide, so I have recompile it after removing all the inlines and optimization: gnatmake -gnatNp -march=native -g -pg -f knucleotide.adb -o knucleotide.gnat_run After running it with the 25M file, I have: $ gprof ./knucleotide.gnat_run -b Flat profile: Each sample counts as 0.01 seconds. % cumulative self self total time seconds seconds calls s/call s/call name 100.00 19.30 19.30 1 19.30 19.30 _ada_knucleotide 0.00 19.30 0.00 1 0.00 0.00 adainit Call graph granularity: each sample hit covers 4 byte(s) for 0.05% of 19.30 seconds index % time self children called name <spontaneous> [1] 100.0 0.00 19.30 main [1] 19.30 0.00 1/1 _ada_knucleotide [2] 0.00 0.00 1/1 adainit [3] ----------------------------------------------- 279444692 _ada_knucleotide [2] 19.30 0.00 1/1 main [1] [2] 100.0 19.30 0.00 1+279444692 _ada_knucleotide [2] 279444692 _ada_knucleotide [2] ----------------------------------------------- 0.00 0.00 1/1 main [1] [3] 0.0 0.00 0.00 1 adainit [3] ----------------------------------------------- Index by function name [2] _ada_knucleotide [3] adainit Why I do not see all the different functions and procedures ? Should I miss something ? Thanks, Olivier
From: Ludovic Brenta on 3 Sep 2009 10:08 Olivier Scalbert wrote on comp.lang.ada: > gnatmake -gnatNp -march=native -g -pg -f knucleotide.adb -o > knucleotide.gnat_run > > After running it with the 25M file, I have: > $ gprof ./knucleotide.gnat_run -b > Flat profile: > > Each sample counts as 0.01 seconds. > % cumulative self self total > time seconds seconds calls s/call s/call name > 100.00 19.30 19.30 1 19.30 19..30 _ada_knucleotide > 0.00 19.30 0.00 1 0.00 0.00 adainit [...] > Why I do not see all the different functions and procedures ? Should I > miss something ? You enabled front-end inlining with -gnatN; GNAT turned the whole program into one procedure. Even then, it should be possible to run the program under valgrind's callgrind tool to get accurate, per-line (indeed per-instruction) execution costs. I don't know whether gprof has such granularity or not. -- Ludovic Brenta.
From: Olivier Scalbert on 3 Sep 2009 11:13
Ludovic Brenta wrote: > You enabled front-end inlining with -gnatN; GNAT turned the whole > program into one procedure. Even then, it should be possible to run > the program under valgrind's callgrind tool to get accurate, per-line > (indeed per-instruction) execution costs. I don't know whether gprof > has such granularity or not. > > -- > Ludovic Brenta. Thanks Ludovic. I will try callgrind tomorrow. Anyway with: $ gnatmake -pg -f knucleotide.adb -o knucleotide.gnat_run I still have: $ gprof -b ./knucleotide.gnat_run Flat profile: Each sample counts as 0.01 seconds. % cumulative self self total time seconds seconds calls s/call s/call name 100.00 24.30 24.30 1 24.30 24.30 _ada_knucleotide 0.00 24.30 0.00 1 0.00 0.00 adainit Call graph granularity: each sample hit covers 4 byte(s) for 0.04% of 24.30 seconds index % time self children called name <spontaneous> [1] 100.0 0.00 24.30 main [1] 24.30 0.00 1/1 _ada_knucleotide [2] 0.00 0.00 1/1 adainit [3] ----------------------------------------------- 306009664 _ada_knucleotide [2] 24.30 0.00 1/1 main [1] [2] 100.0 24.30 0.00 1+306009664 _ada_knucleotide [2] 306009664 _ada_knucleotide [2] ----------------------------------------------- 0.00 0.00 1/1 main [1] [3] 0.0 0.00 0.00 1 adainit [3] ----------------------------------------------- Index by function name [2] _ada_knucleotide [3] adainit So, no more details yet ... Olivier |