Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
28446 Discussions

Threading legacy code with SAVE attribute

David_DiLaura1
309 Views

Colleages,

We are threading legacy code and have encountered the following:

  1. A loop that iterates through a list of equipment data files
  2. Within that loop, and for each iteration, a routine is called multiple times (loop with the outer loop):
    1. The first time it is called in the inner loop, it opens the current equipment data file (determined by the outer loop), reads its data, and does some initial processing. Some of this data is in variables with the SAVE attribute
    2. The 2nd and subsequent times this routine is called in the inner loop, the data file is not opened/read, rather the SAVEd data is used
    3. On these subsequent calls, some of this SAVEd data is written to other files (this step is not germane to the issue at hand)

We want to thread this loop. Not surprisingly, the SAVEd variables get scrambled between (?) threads and the results are rubbish. We have changed the code to write the data previously SAVEd to a temp file (unique to each thread) and (re)read it as necessary. Naturally this is very much slower and defeats any improvement offered by threading. The routine in questions has been declared RECURSIVE.  We are using OpemMP.

Are there alternatives to writing/reading temp files?

David

 

0 Kudos
2 Replies
Paul_Curtis
Valued Contributor I
309 Views

Create an array of the SAVEd items, indexed by the thread_id, ie a unique identifier of each thread, then reference the quantities by active thread, ie myvar(this_thread).

I have found it useful to create a UDT array, call it thread_args(), which includes all the items which are thread-specific to the calculational activity.  If you make this array a target, then your local variables can point to the safe quantities, ie, myvar => thread_args(this_thread)%myvar, and you can put this in once at the top, no change to the rest of the code.

0 Kudos
Roman1
New Contributor I
309 Views

You can declare SAVEd variables as threadprivate.  Each thread would have its own copy of the variable.  For example:

integer,save:: ii
real,save:: aa
!$OMP threadprivate(ii,aa)

 

0 Kudos
Reply