AVISO AL PÚBLICO
CONVOCATORIA PUBLICA Y ABIERTA 15-
Figure 9.1 shows the result of the detailed evaluation. All numbers are normalized against an optimized sequential program version compiled using clang.
In the evaluated programs, ParAγ is able to detect all program locations that were also
parallelized by the domain experts. In all cases ParAγ is able to significantly decrease
the execution time as compared to sequential execution. We validated the statistical significance of all reported speedups with a confidence of 99 percent using the Speedup-Test described by Touati et al. [118]. Our results show both the generality and the effectiveness of our ParAγ.
Detailed Explanation
In the alignment (9.1a) and blackscholes (9.1b) programs, the efficiency of the ParAγ-
parallelized versions falls behind that of the hand-crafted versions using OpenMP or TBB. The difference stems from two factors: First, the OpenMP and TBB programs are compiled with gcc, which in these particular cases is able to create more efficient code. Second, the ParAγ runtime system introduces overhead for allocating heap space for the parallel tasks and for privatization and reduction locations. This overhead is significantly higher than that of the reference systems.
ParAγ ParAγ-dispatch ParAγ-blocked ParAγ-dispatch-blocked Reference 1 2 3 4 5 6 7 8 1× 2× 3× 4× 5×
(a) alignment: ParAγ vs. OpenMP.
1 2 3 4 5 6 7 8 1× 2× 3× 4× 5× (b) blackscholes: ParAγ vs. TBB. 1 2 3 4 5 6 7 8 1× 2× 3× 4× 5×
(c) BiCG: ParAγ vs. Polly.
1 2 3 4 5 6 7 8 1× 2× 3× 4× 5×
(d) gesummv: ParAγ vs. Polly.
1 2 3 4 5 6 7 8 1× 2× 3× 4× 5×
(e) cilksort∗: ParAγ vs. Cilk.
1 2 3 4 5 6 7 8 1× 2× 3× 4× 5× (f) fft: ParAγ vs. Cilk.
Figure 9.1: Evaluation of ParAγ on six programs from different domains, containing
different styles of parallelism. The x-axis shows the number of threads; the y-axis compares
speedup over sequential execution. Parallelization in OpenMP, Cilk, and Intel TBB is
done manually by experts; Polly and ParAγ parallelize automatically.
We see that alignment profits from neither of blocking or runtime dispatch. Indeed, blocking harms performance. This is because the parallelized loop does not have enough iterations to reach the chosen block size. As a result, blocking effectively sequentializes the execution. If the choice to enable blocking is left to the ParAγ runtime system, it therefore disables it based on collected runtime profiling information showing that the iteration count of the loop is too low for blocking to be possibly profitable. The performance improvements achieved by ParAγ on the blackscholes benchmark in contrast
heavily benefits from blocking.
pairalign function requires the privatization of no less than 15 variables at different nesting levels of the loop nest. This necessity is reflected in the OpenMP annotations of the handcrafted parallel version4; if one of those annotations is missed by the developer, the executable will produce incorrect results. ParAγ is able to automatically find variables to
privatize and produces the corresponding code to guarantee correctness without human guidance. In its semi-automatic mode of operation, ParAγ will present all necessary privatization locations to the programmer as described in Chapter 10 and offers to automatically take care for privatization.
In the BiCG (9.1c) and gesummv (9.1d) programs from the PolyBench suite, ParAγ outperforms Polly, the specialized tool for the kind of programs contained in this suite. We can see that blocking is the enabling measure of ParAγ’s performance benefits, whereas dynamic dispatching does not contribute. It does, however, also not impose any significant observable overhead. Due to the loop dominated execution of both programs this is not surprising.
It is, however, surprising that Polly is seemingly even harming the performance of the applications. In case of BiCG it has mainly two problems:
• Polly works on basic block level and is unable to split blocks on demand. Both statements of the innermost loop (see Figure 1.4a) share the same basic block which consequently induces loop-carried dependences over both containing loops.
• Polly is unable to deal with reductions and therefore misses an important opportunity of parallelization.
The slowdown of Polly in this particular benchmark comes from the fact that it not only misses the profitable parallelism, but also parallelizes the loop which initializes the s array to 0, which is not profitable.
In gesummv, Polly finds the right location to parallelize but the generated code based on OpenMP is unable to profitably exploit the exposed parallelism. The speedup would improve, if Polly was able to additionally vectorize the generated code, which it is not in this case.
Note that after the findings and insights resulting from this particular evaluation, Polly has been improved to at least partially overcome the above mentioned limitations. In particular capabilities to detect and exploit reductions have been extended as described in our own work [16].
The fft (9.1f) and cilksort∗ (9.1e) programs implement Fast Fourier Transform and a standard mergesort. Note that the version of cilksort as it is contained in the Cilk suite performs a switch from mergesort to quicksort at a hard coded array size boundary. Cilk and ParAγ (without runtime dispatch) both profit from this boundary when automatically
parallelizing as it effectively causes execution to switch from parallel to sequential once the problem size falls below a given size. As for regular targets of a parallelizer such help cannot be expected, we removed this boundary for our benchmarks (hence the∗ in cilksort∗). As demonstrated in Subsection 7.4.2 (see Figure 7.5) ParAγ makes placing such somewhat artificial boundaries superfluous.
As mentioned earlier, ParAγ is able to make use of dependence annotations placed in the
code by the programmer. Like essentially all applications of the Cilk example suite fft and cilksort mainly consist of recursive functions. As described in Subsection 5.1.1, ParAγ
profits from user provided annotations in such cases and we manually annotated relevant parts. The idea is similar to that of Vandierendonck et al. [79]: hints are only used to improve dependence information while both parallelization and parallel execution stay fully automatic.
As we can see from the results neither of cilksort∗ and fft profits from blocking as the dominating parallelism does not stem from parallel loops. fft also does not profit from runtime dispatch. This is mainly due to a highly specialized and hand-optimized implementation which switches over to specialized function versions to solve smaller sub- problems: specialized implementations which are not parallelized. This corresponds, just like in the original version of cilksort, to an implicit switch from parallel to sequential execution. Later on in this chapter, we will give further insights into the specialized and input dependent execution paths through the fft application.
2mm 3mm adi atax bicg c ho le sky correlation cov ar ia nc e
doitgen durbin dynprog fdtd-2d
fdtd-apml
flo
y
d-
w
arshall gemm gem
v er gesumm v gramsc hmi dt jacobi-1d-imp er jacobi-2d-imp er lu ludcmp m v t reg-detect seidel-2d
symm syr2k syrk trisolv trmm 1
2×
1× 2× 4×
ParAγvs. Clang ParAγvs. ParAγseq
(a) PolyBench. buc k et cilksort fft1 fft2 fft3 fib heat knapsac k lu magic matm ul plu rectm ul spacem ul strassen cholesky (b) Cilk suite. Figure 9.2: Speedups achieved by ParAγ on the PolyBench 3.2 9.2a and Cilk suite 9.2b
with 8 threads on a quad core with Hyper-threading.
cilksort∗ however greatly benefits from runtime dispatching. Indeed, only with runtime dispatching ParAγ is able to achieve any speed-up. In that case, however, it constantly
outperforms the Cilk version.
Note that a significant slowdown can be observed for ParAγ without dispatching, even
when using only one thread. This is because the overhead of creating and scheduling parallel tasks is introduced at every level of recursion and for every problem size. As discussed in detail in 7.4.2 this overhead outweighs the actual productive work, in particular towards the leaves of the recursion tree. Additionally, task stealing hurts data locality, leading to the observed slow-downs for multi-threaded execution.
For both Cilk applications ParAγ with runtime dispatch is able to fully match the
parallelization decisions of the manually crafted implementations; performance with runtime dispatching enabled is comparable to the performance of the Cilk version of both benchmarks.