Parallel and Multi-Core Computing with C/C++ : December 2008

Previous Next
0

Let's get to the good stuff. OpenMP 2.5 did not really specify what constructors should be called with various private/first/lastprivate/threadprivate:

In some cases, it did not even specify that they should apply to non-PODs (Plain'ol Data, i.e. C structs).

OpenMP 3.0 changed that. Beside specifying non-PODs, it also specified precise rules for the constructor sequence that is in line with what the semantics would require.

Firstprivate:
For instance, it would specify that a firstprivate for a class type variable should expect an accessible copy constructor, since it is required to initialize each of the one or more list items private to a thread with the value that the corresponding original item has when the construct is encountered.

Lastprivate:
For a class type variable, it requires an accessible, unambiguous copy assignment operator for the class type. And it requires an accessible, unambiguous default constructor for the class type unless the variable is also specified in a firstprivate clause.

Threadprivate:
This is the most interesting as it differentiates three kinds of initializaton in C++.
1. Without initialization: Object1 o;

  • Default constructor is called
2. Direct initialization: Object1 o( (int)23 );
  • Constructor accepting the argument is called
3. Copy initialization: Object1 o = other_instance;
  • Copy constructor is called

The semantics of this is that for the master thread, global static objects and static class members are constructed before main() is entered in an undefined order.

For the slave threads, the exact point in time of object construction is unspecified, but is has to happen before the thread references it the first time

These changes were a long time coming. It causes what used to be vaguely implied by the 2.5 specification, now to be clearly specified so all compilers can conform. It also allows the users of C++ with OpenMP to have more consistent behavior.

0 Comments Permalink
0

The OpenMP Birds-of-a-Feather session at SC08 was very well attended. The room was full to overflowing, with approximately 60-80 people. while OpenMP had BOFs at SC in prior years, this is actually the first year that OpenMP has had a Booth on the Exhibitor floor as well.

The BOF had many elements, including what is new in OpenMP 3.0. They were:
1. Welcome and summary of ARB news
- 5 mins
- Larry Meadows

2. The three greatest things about OpenMP 3.0 and the three most
important things left out of OpenMP 3.0
- 15 mins
- Tim Mattson

3. Tasking
- 10 to 15 mins
- Alex Duran

4. Extending the OpenMP profiling API for OpenMP 3.0
- 10 to 15 mins
- Oleg Mazurov

5. Announcements:
- 5 mins total
- IWOMP'09 announcement - Matthias Mueller
- OpenMP book examples - Ruud van der Pas

6. Panel "How to kill OpenMP by 2011"
- 35 mins
- Moderator:
Larry Meadows
- Panelists:
Tim Mattson
Bronis de Supinski
Christian Terboven
Jesus Labarta

7. Wrap up
- 5 mins
- Larry Meadows

For a description, you can find lots of detail here, including a downloadable summary card of the 3.0 Specification.

http://openmp.org/

I met a number of people during my afternoon session manning the booth on Wednesday 2-6 pm, including one of the original founder of OpenMP, an instructor on using OpenMP in graduate courses as well as a consultant, among many others. I invite them all to drop me a note here so we can continue our discussion.

One thing that was surprising to many folks was the many compilers that already have 3.0 implementation, despite the specification ratifying only in May 2008. The companies with 3.0 implementation includes IBM, Sun, PGI, and soon Intel. Note I am just reading this from the net and have no insight into other company's or even my own company's release schedule. GNU should have something by 4.4. Same disclaimer.

One thing that happened at the OpenMP BOF was a panel discussion on How to Kill OpenMP by 2012. This is kind of a fun session, especially at the end of a long day to not take yourself too seriously. The point is to showcase all the wrong ways in spreading a de-facto standard.

I have had some experience working with language designs through my various roles as standard rep, and compiler writer. So I thought I would give my $0.02 here on How to Kill OpenMP by 2012:
10. Don't implement the specification as stated.
9. Make it impossible to nail down ambiguities by having no way of addressing defects.
8. Ignore the user forum or suggestions
7. Add everyone's favorite feature, no matter how marginally useful.
6. Make the process as non-transparent as possible, so no one knows when you are ratifying, or even what you are doing.
5. Debate endlessly, on anything, not necessarily having anything to do with the language.
4. Design a feature as completely as possible before releasing it
3. Make no concession when taking a stance on objecting to someone's feature.
2. Form close-nit elitist groups and follow the NIH syndrome.
1. Don't organize any meetings, and when there are meetings, don't follow any rules.

Seriously, I have not found this to be a problem in any of the committees that I am a part of. Otherwise, we would not have made any progress. But we can always do better.

0 Comments Permalink
0

This was one of the question asked at SC 08. I will try to answer that here. I will start and add more as I move through the various topics.

OpenMP 3.0 had better support for C++ in the following areas:

  • Parallelization of RandomAccess Iterator loops with strict canonical operators
  • Threadprivatization of static class members
  • Unsigned loop control variable support
  • Fully specify constructor call requirement in private/first/lastprivate/threadprivate
  • better match with the C++0x memory model

For-Worksharing with Iterator loops:

We specifically enabled C++ RandomAccess iterators and C pointeres to be parallelized with explicit directives.

#include <vector>
void iterator_example()
{
   std::vector<int> vec(23);
   std::vector<int>::iterator it;
   #pragma omp parallel for default(none) shared(vec)
   for (it = vec.begin(); it < vec.end(); it++)
   {
   // do work with *it //
   }
}

I will follow up with more examples.

0 Comments Permalink