david2008 has asked for the wisdom of the Perl Monks concerning the following question:
If @a is sorted, will it be faster than unsorted?my $sum; foreach my $x(@a) { if($x>128) { $sum +=$x; } }
and fun_z fails consistently, will fun_z be calculated at the beginning?fun_a($x) && fun_b($x) &&.....&&fun_z($x)
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: does perl have branch prediction
by BrowserUk (Patriarch) on Jan 29, 2014 at 06:29 UTC | |
There is a consistent but marginal difference when summing an unsorted array compared to summing the same array once sorted:
However, the saving is not sufficient to make it worth while the very high cost of doing the sort:
Perl doesn't attempt to optimise that complex conditional beyond short-circuiting early. I'd be very surprised if pre-compiled C++ would reorder the clauses unless it is very obvious at compile-time that fun_Z() will predominantly produce a false return. It certainly won't reorder them at runtime, and unless all the functions in the conditional are very simple and in-lined, it is doubtful whether the branch-prediction at the chip-level will have sufficient scope to do so. Java might re-order the clauses at runtime via the JIT compiler, if the complex conditional were embedded in a loop. But, it would do so once during the first iteration of the loop and if during that pass fun_Z() returned its atypical response -- ie. if it returned false when it mostly would return true -- then it could result in an overall pessimisation rather than an optimisation, by seeding the branch prediction the wrong way. With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
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.
| [reply] [d/l] [select] |
by david2008 (Scribe) on Jan 29, 2014 at 06:44 UTC | |
| [reply] |
by BrowserUk (Patriarch) on Jan 29, 2014 at 07:06 UTC | |
How can we explain the small time difference between the sorted and unsorted array summing? It is almost certainly down to the cpu instruction cache. Please note, that is just my best guess. I can't think of any easy -- or even feasible given what hardware and software I have available to me -- way of attempting to verify my hypothesis. With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
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.
| [reply] |
by SimonPratt (Friar) on Jan 29, 2014 at 11:12 UTC | |
Its all to do with the workflow at a hardware level. I cant remember specifically all of the stages of processing, but suffice it to say that there are multiple stages of processing. When a program comes to a branch (such as an if), it doesnt pause the processing input for however many cycles, just to wait for the result of the if to pop out the end, it instead uses branch prediction to choose a path to go down (really useful if you're running in a loop, not so useful otherwise) and shovels the next instruction into the first stage of processing. When the branch is finally resolved, it determines whether the results from the next instruction are kept or discarded. If you look at the if you are doing and the dataset, it becomes obvious that a sorted dataset will optimise the branch prediction ability of the CPU, resulting in a minor performance difference (becoming larger as the dataset grows), however as pointed out, sorting the dataset is a lot more costly than the performance gained. (and this is because you are looking at performing many more cycles of processing to sort each item in the array than you will actually save) | [reply] |
by roboticus (Chancellor) on Jan 29, 2014 at 11:53 UTC | |
| [reply] | |
|
Re: does perl have branch prediction
by davido (Cardinal) on Jan 29, 2014 at 07:03 UTC | |
I find about a 12% savings in summing the ordered array using a foreach loop:
This isn't much, really, though time and time again the "sorted" version does win. For the purpose of testing, I'm making some assumptions though; the input data is 50% below the threshold, and 50% above it. However, a sorted list with these characteristics provides additional opportunities for optimization. With a binary search we can (in logarithmic time) find the point in the ordered array to begin summing, thereby eliminating the need to test each element for a value greater 128. By using that technique, and also pushing more of the work into internals, we get a hefty gain:
Here's the benchmark code:
Using List::Util::sum along with an array slice moves the linear loop(s) into internals or XS. List::BinarySearch::binsearch_pos, by default, also moves most of the mechanics (except for the comparator callback) into XS. Plus, the binary search finds the first element greater than 128 in just a few iterations. The higher the ratio of disqualified elements to qualified, the better the results will be, since the binary search will quickly disqualify a higher proportion of the initial array. Dave | [reply] [d/l] [select] |
|
Re: does perl have branch prediction
by kcott (Archbishop) on Jan 29, 2014 at 06:43 UTC | |
G'day david2008, "I came over an interesting post in stackoverflow It explains that in Java/C++ processing a sorted array is faster than an unsorted." Firstly, it reports an observation; it doesn't "explain" a fact. Secondly, if you read further, you'll find the OP writes things like "I did investigate a bit further, and things are "funny"." and "... so it really has nothing to do with the data being sorted, ...". Use Benchmark to compare the running times of Perl code. What you can do in Perl is this:
Output:
To what degree the processing involved in sorting the data offsets any gains in a reduction of iterations will depend on the size of the array and the value of the elements (for instance, if all values are greater than 128, then sorting would be entirely wasteful and useless). -- Ken | [reply] [d/l] [select] |
|
Re: does perl have branch prediction
by Anonymous Monk on Jan 29, 2014 at 07:59 UTC | |
CPUs have branch prediction. | [reply] |
|
Re: does perl have branch prediction
by hdb (Monsignor) on Jan 29, 2014 at 07:07 UTC | |
With respect to your condition fun_a($x) && fun_b($x) &&.....&&fun_z($x): As C++ like Perl short-circuits && (Short-circuit_evaluation), it should not re-order the evaluation as there can always be side-effects (like changing the value of a global variable) in fun_z($x). The program logic could be very different even if the (boolean) result of the expression is the same. | [reply] [d/l] [select] |
|
Re: does perl have branch prediction
by oiskuu (Hermit) on Jan 29, 2014 at 12:24 UTC | |
Note that CPUs (these days) support conditional instructions; good compilers make use of these. Loop body such as is likely compiled with a cmov on x86/x86_64 and therefore incurs no branch misprediction penalty. As for the perl version: the effects of misprediction are practically negligible, lost in the noise.
| [reply] [d/l] [select] |
|
Re: does perl have branch prediction
by Anonymous Monk on Jan 29, 2014 at 05:29 UTC | |
Awww:D | [reply] |
by david2008 (Scribe) on Jan 29, 2014 at 06:38 UTC | |
The output is 37500002500000 sorted: 6 wallclock secs ( 5.61 usr + 0.00 sys = 5.61 CPU) 37500002500000 random: 6 wallclock secs ( 5.81 usr + 0.00 sys = 5.81 CPU)There is a difference but not as dramatic as in java or c++ (from the stack overflow post) What is the correct interpretation of the results? | [reply] [d/l] |