in reply to threading a perl script

Contrary to popular opinion, there is some scope for performance gains through threading with this pattern of application usage.

Whether those performance gains are realisable, or worth the effort of doing so, depends entirely upon what DO STUFF FOR EACH LINE actually consists of?

For example, in the following, the one-liner simply reads a 1GB/16 million line file with no further processing. This forms a base line for how fast you can get the data from disk into memory:

C:\test>timeit \perl64\bin\perl.exe -nle1 1GB.dat Took: 9.687471720 seconds C:\test>timeit \perl64\bin\perl.exe -nle1 1GB.dat Took: 9.544258000 seconds C:\test>timeit \perl64\bin\perl.exe -nle1 1GB.dat Took: 9.708372520 seconds

As you can see, on my system that baseline is reasonably consistently something just under 10 seconds.

In the following, reading the same file, but this time performing about the simplest search and action possible:

C:\test>timeit \perl64\bin\perl.exe -nle\"/\*/ and ++$c }{ print $c\" +1GB.dat 10217571 Took: 11.682412240 seconds C:\test>timeit \perl64\bin\perl.exe -nle\"/\*/ and ++$c }{ print $c\" +1GB.dat 10217571 Took: 11.904963960 seconds C:\test>timeit \perl64\bin\perl.exe -nle\"/\*/ and ++$c }{ print $c\" +1GB.dat 10217571 Took: 12.945696440 seconds C:\test>timeit \perl64\bin\perl.exe -nle\"/\*/ and ++$c }{ print $c\" +1GB.dat 10217571 Took: 12.128623440 seconds

There is consistently 2 to 2.5 seconds of processing time. In theory, if you could split that processing time across 2 cores, you could reduce the runtime by around a second.

And that is a conservative estimate, because most of the time attributed to IO, is time spent waiting with an idle cpu. so, if you could utilise that idle cpu to perform the processing of the current record, whilst the system fetches the next, you could (theoretically) get the elapsed time back down close to the IO baseline and save the full 2 to 2.5 seconds.

That said, achieving that using Perl's current threading mechanisms--it is the state sharing mechanisms that are the bottleneck--is very difficult, bordering on the impossible. It is quite difficult to achieve in any language not just Perl.

And to achieve it requires that you make a very simple program considerably more complicated. So you have to ask yourself, is a (at best) 2.5 second saving on 12.5 seconds worth that effort and complication? For the case of the simple example above, almost certainly not. For a 20% saving to be of significant value it would have to be a pretty big file.

But, if the processing of each line is substantially more complex, sufficient to raise the IO to cpu ratio significantly, and the files were large enough to make the overlapping of those two components worth the effort involved, then there is some scope for doing that using threading.

Mind you, it would be simpler still if Perl gave us access to the asynchronous/overlapped IO facilities available in most modern OSs, but that is a different discussion.


Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.

Replies are listed 'Best First'.
Re^2: threading a perl script
by vkon (Curate) on Apr 23, 2011 at 06:12 UTC
    Good message, pleasant reading.

    Now, given that in a 10-second processing, gives a saving 2 seconds by parallelizing algorithm using threads - makes me think, that thread usage is even narrower than I initially thought.

    Threaded perl some 10-15% slower than unthreaded one, and we're paying this price every time to eventually have a possibility to save 20% of time?
    (after reorganizing flow of program, which will give some 80% or more of added complexity :) )

    Add to this that most GUI libraries (actually, all GUI libraries) are also single-threaded,

    Unthreaded perl rulez! :)

    Vadim.

      If that is all you took from my post, then you shouldn't be celebrating.

      If all the programs you write do nothing more complicated than wc or fgrep; if in your world a 1GB file represents nothing more important than say 1 day's twaterrings, and you only need to count the number of '!'s used; if between reading and writing your important data you need to do nothing of any consequence; then stick with your un-threaded perl, because it can do nothing very, very quickly.

      On the other hand, if you are (say) a bio-geneticist. And that 1GB of data represents 10,000 x 100k base sequences, each of which need to be fuzzy matched at every offset, against each of 25,000 x 25-base sub-sequences; a process that on a single core takes a week or more, then you'll be rather more interested in using perl's threading to reduce that to under a day using a commodity 8-core box. And even more grateful for that threading when you're given access to the departmental 128-core processor, and your script completes in under 2 hours with nothing more than a change of command line argument.


      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.
        my everyday programming indeed mostly text processing - just enough for single-threaded perl.
        This is not simply 'wc' or grep like you said, but some text transforms, with either XML modules, or somehting like that
        good enough for single-threaded perl

        Actually I do not agree with your point, that I will have much benefit from threaded perl on multicore for complicated tasks.
        The great drawback of perl threads - they are heavy - and also unstable - will make me find other solution.
        Increasing CPU power is not the way to go.
        Most probably I will use number-crunching libraries from perl (lapack or maybe specialized library).

        Perl has owervelming strength in text processing, GUI, etc, its compact and nice, plus we have CPAN - that's brilliant.
        But using it for calculation-intensive task is just wrong.
        and then - when program speed is not enough - increasing number of CPUs is even worse :)

        addition: we have a fresh fork-related bug for windows perl today - http://rt.perl.org/rt3/Ticket/Display.html?id=89142 - at least Active Perl 5.12.1 and 5.10.0 do crash on that simple program.
        threads are just not stable enough.

        PS do 128-core processor exist? :o :o