VivaMP, system of detecting errors in the code of parallel C++ programs using OpenMP

  • 336 views
Uploaded on

The article lists the results of investigation of mistakes made by programmers using C++ and OpenMP. Static analysis is offered for automatic detection of these errors. The description of VivaMP …

The article lists the results of investigation of mistakes made by programmers using C++ and OpenMP. Static analysis is offered for automatic detection of these errors. The description of VivaMP analyzer integrating into Visual Studio environment and implementing the set task is described.

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
    Be the first to like this
No Downloads

Views

Total Views
336
On Slideshare
0
From Embeds
0
Number of Embeds
0

Actions

Shares
Downloads
5
Comments
0
Likes
0

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. VivaMP, system of detecting errors in thecode of parallel C++ programs usingOpenMPAuthors: Alexey Kolosov, Andrey Karpov, Evgeniy RyzhkovDate: 20.11.2009At present, Viva64 and VivaMP software products are included in PVS-Studio as parts of it and are nolonger distributed as separate applications. Please use PVS-Studio program to obtain the necessarypossibilities of code verification.AbstractThe article lists the results of investigation of mistakes made by programmers using C++ and OpenMP.Static analysis is offered for automatic detection of these errors. The description of VivaMP analyzerintegrating into Visual Studio environment and implementing the set task is described.1. IntroductionAccording to the survey by Evans Data company conducting surveys among software developers, thegeneral number of programmers will be 17 million people by 2009[1]. Currently, 40% of them use C++and 70% are involved in development of multi-thread applications now or are planning to start it duringthe year [2]. According to the same survey 13,2% of these developers think that the main problem ofthese developments is the lack of software tools for creation, testing and debugging of parallelapplications. Consequently, 630.000 programmers are directly interested in solving the task ofautomatic search of errors in the source code.The aim of this work is to create a static code analyzer intended for automatic detection of such errors.The research considered C++ language for it is the code in this language to which high-performancerequirements are made. As support of OpenMP technology is embedded into Microsoft Visual Studio2005 and 2008 and some specialists believe that it is OpenMP that will gain the greatest popularity [3],we considered this very technology (which is used also for C and Fortran languages besides C++).Analysis of reviews of debuggers for parallel programs shows that the situation in this sphere is far froman ideal. Concerning debugging of programs written in C++ and using OpenMP, TotalView and IntelThread Checker are mentioned. But both tools are intended for dynamic operation mode. Until recentlythe procedure of static analysis of OpenMP programs hasnt been mastered. Perhaps, the only examplewe can give is rather a quality diagnosis provided by Sun Studio compiler. VivaMP static analyzer hastaken this place.2. Using static analysis for debugging of parallel programsMost of the currently existing tools for debugging parallel programs are dynamic analyzers presupposingdirect execution of the program being analyzed. This approach has some advantages but there aredisadvantages too.
  • 2. Dynamic analysis presupposes data collection only during execution of a program, and consequently it isnot guaranteed that the whole code will be tested. Moreover, when using this approach a programmermust repeat the same actions many times or use tools of automatic testing to imitate users actions.Besides, during dynamic analysis the code of the application being debugged is tooled and this reducesthe programs performance and sometimes can cause failures. As collection and analysis of informationis performed, as a rule, at the end of dynamic analysis to increase performance, in case of a critical errorin the analyzed application all the results will be lost.Finally, dynamic analysis doesnt always allow you to detect a concrete code fragment leading tounexpected behavior.Static analysis allows you to look through the whole source code of an application, detects dangerouscode sections and doesnt require additional efforts from a programmer. The disadvantage of staticanalysis is that it doesnt allow you to check behavior depending on a user. False responses are onemore problem and reduction of their number demands additional efforts when developing the analyzer.The issue of using static analysis when developing parallel programs is considered in detail in the article[4].VivaMP analyzer uses tree walk analysis. Besides, there are other types of static analysis implyingmodeling of execution of a program, calculation of possible values of variables and ways of codeexecution. Static analysis as a means of diagnosing errors in parallel programs was chosen because thisapproach allows us to detect many errors which dynamic analyzers fail to diagnose. Now lets considerthe errors themselves in detail.3. Errors diagnosedThe list of possible errors not detected by Visual Studio compiler has been composed as the result ofresearch of the works devoted to parallel programming using OpenMP and also on the basis of theauthors personal experience. All the errors can be divided into four main categories: • Insufficient knowledge of OpenMP syntax. • Insufficient understanding of OpenMPs operation principles. • Incorrect work with memory (unprotected access to main memory, absence of synchronization, incorrect variable-access mode etc). • Performance errors.The first three types of errors are logic errors which lead to change of the programs working logic, tounexpected results and (in some cases) to program crash. The last category unites errors leading toperformance decrease.Lets give examples of errors of each category and their brief description.3.1. Absence of parallel key-wordLets consider a simplest error which can occur because of incorrect writing of OpenMP directives. Asthese directives have rather a complex format, any programmer can make this mistake due to this orthat reason. The example of correct and incorrect code is given in Figure 1.// Incorrect:
  • 3. #pragma omp for... // for loop// Correct:#pragma omp parallel for... // for loop// Correct:#pragma omp parallel{ #pragma omp for ... // for loop}Figure 1. Example of an error caused by absence of parallel key-wordThe fragment of incorrect code given above will be successfully compiled by the compiler even withoutany warnings. The incorrect directive will be ignored and the loop following it will be executed only byone thread. No paralleling will take place and it will be difficult to see this in practice. But the staticanalyzer will point at this potentially incorrect code section.3.2. Incorrect use of locksIf a programmer uses functions like omp_set_lock for synchronizing and/or protecting an object fromsimultaneous writing, each thread must contain calls of the corresponding functions omp_unset_lockand with the same variables. An effort to release a lock captured by another thread or absence of call ofan unlocking function can lead to errors and an eternal waiting during program execution. Lets consideran example of code (see Figure 2):// Incorrect:omp_lock_t myLock;omp_init_lock(&myLock);#pragma omp parallel sections{ #pragma omp section { ... omp_set_lock(&myLock); ...
  • 4. } #pragma omp section { ... omp_unset_lock(&myLock); ... }}// Incorrect:omp_lock_t myLock;omp_init_lock(&myLock);#pragma omp parallel sections{ #pragma omp section { ... omp_set_lock(&myLock); ... } #pragma omp section { ... omp_set_lock(&myLock); omp_unset_lock(&myLock); ... }}// Correct:omp_lock_t myLock;omp_init_lock(&myLock);
  • 5. #pragma omp parallel sections{ #pragma omp section { ... omp_set_lock(&myLock); ... omp_unset_lock(&myLock); ... } #pragma omp section { ... omp_set_lock(&myLock); ... omp_unset_lock(&myLock); ... }}Figure 2. Example of incorrect use of locksThe first example of incorrect code will lead to an error during execution of the program (a threadcannot release the variable captured by another thread). The second example will sometimes workcorrectly and sometimes lead to a hang. It will depend on what thread finishes last. If it will be thethread in which lock of the variable is performed without its release, the program will give the expectedresult. In all the other cases there will be an eternal waiting for release of the variable captured by thethread working with the variable incorrectly.Now lets consider another error in detail and give the corresponding rule for the analyzer.3.3. Unprotected access to main memoryThis error can occur in any parallel program written in any language. It is also called a race condition andconsists in that the value of a shared variable changed simultaneously by several threads can beunpredictable as the result. Lets consider a simple example for C++ and OpenMP (see Figure 3):// Incorrect:
  • 6. int a = 0;#pragma omp parallel{ a++;}// Correct:int a = 0;#pragma omp parallel{ #pragma omp atomic a++;}Figure 3. Example of a race conditionThis error can be also detected with the help of the static analyzer. Here is a rule according to whichVivaMP static analyzer can detect this error:"Initialization or modification of an object (variable) in a parallel block must be considered dangerous ifthe object is global in relation to this block (shared for threads)".To global objects in relation to a parallel block refer: • Static variables. • Static class members (not implemented in VivaMP 1.0). • Variables defined outside a parallel block.An object can be both a simple-type variable and a class-instance. To operations of object change refer: • Passing of an object into a function by a non-constant link. • Passing of an object into a function by a non-constant pointer (not implemented in VivaMP 1.0). • Change of an object when performing arithmetic operations or assignment operations. • Call of a non-constant method of an object.At first sight there is nothing complicated. But to avoid false responses we have to introduce manyexceptions. The code being checked should be considered safe if: • The code is located outside a parallel block ("parallel" directive is absent). • Modification of an object is protected by "atomic" directive. • The code is located in a critical section defined by "critical" directive. • The code is located in a critical section created by functions of omp_set_lock type. • The code is located in the block of "master" directive. • The code is located in the block of "single" directive.
  • 7. • "threadprivate" directive or "private", "firstprivate", "lastprivate" or "reduction" expressions are applied to an object (variable). This exception doesnt concern static variables and static class fields which are always shared. • Initialization or modification of an object is performed inside for operator (inside the operator itself and not inside the loop body). Such objects are automatically considered private according to OpenMP specification. • Modification of an object is performed inside a section defined by section directive.Following this rule and the listed exceptions the analyzer can detect an error by the code tree.In conclusion we would like to say that you can find a more detailed list of the errors detected duringresearches and more detailed descriptions of them on the site of VivaMP project.Now lets see the description of the analyzer itself.4. VivaMP analyzerVivaMP analyzer was developed on the basis of VivaCore code analysis library and together with Viva64comprises a single line of products in the sphere of testing resource-intensive applications. Viva64 isintended for searching errors relating to porting 32-bit software on 64-bit platforms. VivaMP is intendedfor testing parallel applications built on the basis of OpenMP technology. Like Viva64, VivaMP integratesinto Visual Studio 2005/2008 development environment adding new commands to the interface. Settingof the analyzer is performed through the environment-standard mechanism and diagnostic messagesare displayed in the same way as those of a standard compiler - in the windows Error List and OutputWindow. Besides, there is a detailed description of errors given in the analyzers Help system integratinginto Visual Studio Help. Context help is implemented through the standard environments mechanism.VivaMP analyzers interface integrated into Visual Studio environment, is shown in Figure 4.
  • 8. Figure 4. VivaMP interfaceAt present the first version of the analyzer is released and you can see information about it here:http://www.viva64.com/vivamp-tool. The first VivaMP version diagnoses 19 errors, and the amount of
  • 9. materials collected and experiments results allow us to significantly increase this number (minimumtwice) in the next versions. Below are listed brief descriptions of the errors diagnosed: • Absence of "parallel" key-word. • Absence of "omp" key-word. • Absence of "for" key-word (each thread will execute a loop completely, the work wont be shared between the threads). • Embedded paralleling of "for" loop. • Absence of "ordered" directive in an ordered loop. • Redefining of the number of threads in parallel code. • Asymmetrical use of locking/unlocking functions. • Dependence of the codes behavior on the number of threads executing it (use of "omp_get_num_threads" function in an arithmetic operation). • Redefining of the ability of embedding paralleling in parallel code. • Simultaneous use of the shared resource (unprotected function call). • Use of "flush" directive for pointers. • Use "threadprivate" directive. The directive is dangerous as it influences the whole file. It is recommended to use local variables or explicitly define the type of access in each parallel block. • Unprotected definition of a static variable in parallel code. • Unprotected simultaneous operation with a variable. • Simultaneous change of a variable by calling a function. • Simultaneous change of an object by calling a function. • A link-type variable cannot be defined as local. • A pointer cannot be a local variable. • A variable defined as "lastprivate" is not changed in the lexically last parallel section.Besides already achieved results, we continue searching new errors. If you, dear colleagues, know somepatterns of such errors we would be glad if you told us about them by using contact information on theabove mentioned site of VivaMP project.Besides, it would be interesting to test our analyzer on real serious projects using OpenMP technology. Ifyou are developing such a project and need a code analyzer, please contact us.References 1. Timothy Prickett Morgan. Evans Data Cases. Programming Language Popularity: [http://www.viva64.com/go.php?url=190], 14.12.2006. 2. Janel Garvin. Evans Data: Market Situation and Predictions: [http://www.viva64.com/go.php?url=191], 8.04.2008 3. Michael Suess. Why OpenMP is the way to go for parallel programming: [http://www.viva64.com/go.php?url=119], 12.08.2006. 4. E.A. Ryzhkov, O.S. Seredin. Using static code analysis technology when developing parallel programs. Izvestiya TSU. Technical sciences. Issue 3. - Tula: TSU Publishing House, 2008. - 267 pp. Pp. 191 - 196. 5. Alexey Kolosov, Evgeniy Ryzhkov, Andrey Karpov. 32 OpenMP Traps for C++ developers. RSDN Magazine #2-2008. Pp. 3 - 17.