Difference between revisions of "OpenMP support"
(Some early idea of implementing OpenMP in clean Pascal syntax.) |
|||
Line 6: | Line 6: | ||
=== Proposal 1 === | === Proposal 1 === | ||
− | < | + | |
+ | ==== Foreword ==== | ||
+ | |||
+ | At first, I must admit that some parts of the OpenMP specification I still don't understand. They did a terrible good job throwing away all common terms ever used in multi threading context, and invented their own ones. | ||
+ | |||
+ | ==== Syntax vs. Compiler directives ==== | ||
+ | |||
+ | OpenMP for C and C++ is implemented by using compiler directives mainly due to the reasons of source code compatibility (or: standards compliance). So a ''conforming'' program is intended to behave the same regardless if the actual compiler compiling the program supports those special pragmas or not. | ||
+ | |||
+ | For FreePascal I don't think this is the way to go, because first it changes comments into code and second, it makes the program far less readable. For C programs this doesn't seem to be an issue, if you get my meaning. But in my opinion, readability is a far more important issue than compatibility to older/different compilers. If all else fails, a preprocessor could be provided to strip out the parallel specific stuff, as has been suggested by Marco. | ||
+ | |||
+ | Well, enough talk, I start with the easier directives which are luckily the more fundamental ones. | ||
+ | |||
+ | ==== parallel ==== | ||
+ | |||
+ | The <code><b>parallel</b></code> construct can only be used for a structured block. So in Pascal it should be followed by a <code><b>begin</b></code>/<code><b>end</b></code> pair anyway. If this could be made a requirement (no one-liners allowed), even the clauses that come with the <code><b>parallel</b></code> construct can mostly be done in a clean and readable way. So if you take a look at the A.4.1.c example of the OpenMP 2.5 specification, the Pascal version could look like this: | ||
+ | |||
+ | <b>procedure</b> SubDomain (<b>var</b> x : <b>array of</b> Float; | ||
+ | istart : Integer; | ||
+ | ipoints : Integer) | ||
+ | <b>var</b> | ||
+ | i : Integer; | ||
+ | <b>begin</b> | ||
+ | <b>for</b> i := 0 <b>to</b> ipoints - 1 <b>do</b> | ||
+ | x[istart + i] := 123.456; | ||
+ | <b>end</b> <i>{SubDomain}</i>; | ||
+ | |||
+ | <b>procedure</b> Sub (<b>var</b> x : <b>array of</b> Float); | ||
+ | <i>// Variables declared here should have </i><code><b>shared</b></code><i> context.</i> | ||
+ | <i>// This would include the function's parameters then...</i> | ||
+ | <b>begin</b> | ||
+ | <b>parallel</b> | ||
+ | <i>// Variables declared here have </i><code><b>private</b></code><i> context.</i> | ||
+ | iam : Integer; | ||
+ | nt : Integer; | ||
+ | ipoints : Integer; | ||
+ | <b>begin</b> <i>// of parallel section</i> | ||
+ | iam := OMP.Get_Thread_Num; <i>// OMP library calls.</i> | ||
+ | nt := OMP.Get_Num_Threads; | ||
+ | |||
+ | ipoints := Length (x) <b>div</b> nt; <i>// size of partition</i> | ||
+ | istart := iam * ipoints; <i>// starting array index</i> | ||
+ | |||
+ | <b>if</b> iam = Pred (nt) <b>then</b> | ||
+ | ipoints := Length (x) - istart; <i>// last thread may do more</i> | ||
+ | |||
+ | SubDomain (x, istart, ipoints); | ||
+ | <b>end</b> <i>{parallel}</i>; | ||
+ | <b>end</b> <i>{Sub}</i>; | ||
+ | |||
+ | <b>var</b> | ||
+ | arr = <b>array</b>[0 .. 9999] <b>of</b> Float; | ||
+ | <b>begin</b> <i> // Main program</i> | ||
+ | Sub (arr, 10000); | ||
+ | <b>end</b>. | ||
+ | |||
+ | |||
+ | ==== More constructs ==== | ||
+ | |||
+ | To be continued... | ||
+ | |||
+ | [[User:V.hoefler|V.hoefler]] | ||
+ | |||
+ | |||
+ | === Proposal 2 === | ||
=== Proposal 2 === | === Proposal 2 === | ||
<not yet done> | <not yet done> |
Revision as of 23:33, 25 July 2006
What is OpenMP?
OpenMP is an API accessed by language directives to do multi threaded programming, see also http://www.openmp.org. Currently, there is only OpenMP syntax defined for C and Fortran. This page tries to collect some stuff to settle down pascal syntax for it.
Pascal syntax for OpenMP
Proposal 1
Foreword
At first, I must admit that some parts of the OpenMP specification I still don't understand. They did a terrible good job throwing away all common terms ever used in multi threading context, and invented their own ones.
Syntax vs. Compiler directives
OpenMP for C and C++ is implemented by using compiler directives mainly due to the reasons of source code compatibility (or: standards compliance). So a conforming program is intended to behave the same regardless if the actual compiler compiling the program supports those special pragmas or not.
For FreePascal I don't think this is the way to go, because first it changes comments into code and second, it makes the program far less readable. For C programs this doesn't seem to be an issue, if you get my meaning. But in my opinion, readability is a far more important issue than compatibility to older/different compilers. If all else fails, a preprocessor could be provided to strip out the parallel specific stuff, as has been suggested by Marco.
Well, enough talk, I start with the easier directives which are luckily the more fundamental ones.
parallel
The parallel
construct can only be used for a structured block. So in Pascal it should be followed by a begin
/end
pair anyway. If this could be made a requirement (no one-liners allowed), even the clauses that come with the parallel
construct can mostly be done in a clean and readable way. So if you take a look at the A.4.1.c example of the OpenMP 2.5 specification, the Pascal version could look like this:
procedure SubDomain (var x : array of Float; istart : Integer; ipoints : Integer) var i : Integer; begin for i := 0 to ipoints - 1 do x[istart + i] := 123.456; end {SubDomain}; procedure Sub (var x : array of Float); // Variables declared here should haveshared
context. // This would include the function's parameters then... begin parallel // Variables declared here haveprivate
context. iam : Integer; nt : Integer; ipoints : Integer; begin // of parallel section iam := OMP.Get_Thread_Num; // OMP library calls. nt := OMP.Get_Num_Threads; ipoints := Length (x) div nt; // size of partition istart := iam * ipoints; // starting array index if iam = Pred (nt) then ipoints := Length (x) - istart; // last thread may do more SubDomain (x, istart, ipoints); end {parallel}; end {Sub}; var arr = array[0 .. 9999] of Float; begin // Main program Sub (arr, 10000); end.
More constructs
To be continued...
Proposal 2
Proposal 2
<not yet done>