Adding an 'if' clause to the 'simd' construct

Comments and discussion of the 4.1 OpenMP Draft specifications. Comment period ends September 30, 2015. See to download the specifications. (Read Only)
Forum rules
The OpenMP Forums are now closed to new posts. Please visit Stack Overflow if you are in need of help:
Posts: 1
Joined: Tue Aug 18, 2015 7:17 am

Adding an 'if' clause to the 'simd' construct

Post by gcivario »

Dear members of the OpenMP standardisation committee,
to address issues of the kind I describe hereafter, I would like to request the addition of an if clause to the simd construct.
This clause would only be supported for conditional statements known at compilation time, therefore only acting as a on/off switch to the entire construct while compiling the code.

This would give for example:
In C

Code: Select all

   #define VECTORIZE 1
   #pragma omp simd if(VECTORIZE)
   for ( i=0; i<N; i++ )
In C++

Code: Select all

  template<bool vectorize> myFunction() {
      #pragma omp simd if(vectorize)
      for ( i=0; i<N; i++ )
In Fortran

Code: Select all

   integer, parameter :: vecparam = 2
   !$omp simd if(vecparam>1)
   do i = 0, N
The most useful use of this would be for C++ templated code, but this would also be of interest on all 3 languages for selectively enable or disable some simd constructs at compilation time.
Moreover, the compile-time limitation for the evaluation of the if parameter makes it a trivial addition to the existing implementation of the simd construct.


Now a bit of somewhat lengthy explanations as for the reasons of this request:

In a C++ code my colleagues and I are currently developing, we have a large vectorisable loop, whit a rather complicated body, which means that the compiler won't vectorise by itself. In addition, some run-time parameters of the code might slightly change the loop body, adding some extra actions.
In order to keep the code as factorised as possible, while sacrificing neither the performance, nor the maintainability, we decided to take a templated approach like the following:

Code: Select all

template< bool extraCheck > void computeBody(...) {
    // some stuff here
    // the big loop here
    for ( long i = 0; i < N; i++ ) {
        // do something complex
        // special case
        if ( extraCheck ) {
            // do some stuff that are not so vector friendly
        // some more complex stuff

void compute( bool extraCheck, ...) {
    if ( extraCheck )
The point of this construction is that all the complex part being identical for extraCheck being true or false, it can be kept in the same function while still having a fully optimised code since the parameter being known at compilation time, the compiler will generate two different versions of the function (one with the optional part of the code and one without) removing the if statement altogether.
This worked great so far.

But now that we want to add an OpenMP simd directive, we face an issue: we cannot relate the directive to the template parameter. Indeed, the common part of the loop is perfectly fine for vectorisation and will greatly benefit from the addition of the simd directive. The optional part however is absolutely not vector friendly, and although the generated code is valid, the overall performance is divided by 3 compared to the non-vectorised version. So ideally, we would need a way of inserting the simd construct only when the extra checking code is off. The requested enhancement of the standard would permit exactly that.

We are of course well aware that we can get the same sort of feature based on pre-processor macros. However, this can only be achieved with very convoluted and hard to read and to maintain code. This is why, this simple addition to the simd construct seems on the long term a much better option.

Thank you for reading this far and for considering my request.

Gilles Civario

Posts: 12
Joined: Tue Jul 14, 2015 9:35 am

Re: Adding an 'if' clause to the 'simd' construct

Post by Spreis »

Probably having general 'if' clause (with dynamic condition known before entering the construct) makes sense for simd construct same way as for parallel construct. This general 'if' might subsume compile-time-only use case: compilers might optimize away one of the branches if condition is known at compile time otherwise leave both SIMD and scalar code in the binary with dynamic check once per loop entry.