OpenMP issues

The PVS-Studio product contains a set of static analysis rules intended to detect errors in code of parallel C/C++/C++11 programs written with the use of OpenMP technology.

This set of rules was earlier shipped as a separate solution called VivaMP. Now the VivaMP static analyzer is included into the PVS-Studio software product and the name "VivaMP" is associated with the corresponding set of rules to search for parallel errors.

The set of specialized rules of VivaMP lets you detect some errors causing race conditions, ineffective use of processor time and so on. The main difficulty of detecting such defects at the stage of testing is their irregular character. The static analyzer works with the source code and reviews all the possible ways of program execution. So it can find some of these very rare errors. On the other hand, static analysis cannot detect much of what dynamic analyzers like Intel Parallel Inspector can. We should not try to come to only one approach in detecting parallel errors. Static and dynamic analyses supplement each other well here.

Let's consider some examples of parallel errors detected by PVS-Studio.

Unprocessed exceptions in parallel sections

#pragma omp parallel for
for (size_t i = 0; i != n; ++i) {
  float *array = new float[10000]; 
  delete [] array;
}

This code will lead to incorrect behavior of the program and most likely its crash if a memory allocation error occurs.

The error is related to throwing of an exception from a parallel section. According to OpenMP specification, if you use exceptions inside a parallel section, all these exceptions must be processed inside this section. If you use the new operator inside a parallel section, you must provide for capture of the exception that will be generated when the memory allocation error occurs, according to the C++ language standard.

The error causing a race condition

int a = 0;
#pragma omp parallel for num_threads(4)
for (int i = 0; i < 100000; i++) {
	 a++;
}

Race condition occurs when several threads of a multi-threaded application are trying to simultaneously get access to data and at least one of these threads is performing writing. Race conditions may lead to unpredictable results and they are often difficult to detect. Sometimes consequences of a race condition reveal themselves only long time later and in a quite different part of an application. Besides, such errors are extremely difficult to recall.

It is quite effective to detect at least some of such errors with the help of static analysis at the very stage of writing the code.

Initialization of static variables inside parallel sections

pragma omp parallel
{
  static int st = Calc();
  ...
}

A static variable will begin the initialization process in several threads at once, which may cause an unexpected result. You must use synchronization mechanisms to initialize the variable only in one of the threads and do not let other threads use it until the initialization process is over.

The error of inattentive use of OpenMP directives

void Foo() {
  #pragma omp for
  for (int i = 0; I < n; ++i)
	...

The key word parallel is missing here by accident. Against the programmer's expectations, the loop will be executed only by one thread.

The error of inattentive use of one of OpenMP functions

#pragma omp parallel 
{ 
  omp_set_num_threads(2); 
  ...
}

You must not redefine the number of threads inside a parallel loop. It will cause an error when executing the program and its crash.

To learn more about various samples of parallel errors, see the article "32 OpenMP traps for C++ developers" and "An unsuccessful attempt to compare PVS-Studio (VivaMP) and Intel C/C++ ("Parallel Lint")".

Advantages of using static analysis to detect defects in parallel programs

The static code analysis methodology employed in the PVS-Studio tool has significant advantages over other types of analysis. Errors in parallel programs are usually difficult to recall and detect during the debugging process. The main advantage of static analysis is that you do not need to launch applications and that it is independent from the hardware environment. The procedure of code check cannot damage the code itself in any way. The analysis process is completely controlled by person and it is the programmer who decides if it needs modification.

The PVS-Studio tool is shipped together with the knowledge base on parallel code (help system, articles, samples) that will improve programmers' knowledge in the sphere of parallel programming.