flush an array element

General OpenMP discussion

flush an array element

Postby kasuistry » Tue May 27, 2008 11:51 am

Dear all,

I tried to use "the flush construct" for updating an element of an array.

For example,
Code: Select all
int s[LEN];

#pragma omp parallel default(shared)
{
     lock();
     #pragma omp flush(s[i])
          s[i] = something;
     #pragma omp flush(s[i])
     unlock();
}

It looks fine, but g++ regards this as an error. The reason is the variable list in the flush quote
isn't permitted to contain any array element. After taking a look at the draft manual obtained
from the official site, it only shows how to flush the whole array, "#pragma omp flush(s)". I
don't think it's an efficient way to handle this situation, but the measurement I made shows
there is no significant difference between small and large LEN. Could any experienced ones
give me an explanation about that or a proper way to flush an array element?

Thanks in advance,
kasuistry
kasuistry
 

Re: flush an array element

Postby ejd » Tue May 27, 2008 4:55 pm

Up through the OpenMP V2.5 spec, as you have found, there is no way for the user to flush an element of an array. Depending on what you are doing (i.e., the format of the assignment), you might be able to use "atomic" on the array element. This will gaurantee that the element is only updated by one thread at a time and that the value is "flushed". I should also note that it will depend on the compiler implementation of atomic as to whether or not this is very efficient.

As for your question about why you don't see any significant difference between flushing arrays with a small or a large size, you have to think about what is being done and how the compiler handles it. A flush is either saying that the value in the cache needs to be written back to memory or that the value needs to be read from memory (into the cache). cache and main memory are both pretty fast now days and a cache line will contain multiple values of the array and so multiple words can be transferred at a time. Also, the compiler has some idea about what has been updated and needs to be written back, so not all values have to be written back. So basically, you would have to have a very large array contained in a very large cache or do a lot of "flushing" in your program, before it added up to anything really noticable.

I have not gone into all the deatils and if you really want to understand it fully, I will see if I can find a good book covering the topic. Hopefully though, this sort of answers your question.
ejd
 
Posts: 1025
Joined: Wed Jan 16, 2008 7:21 am

Re: flush an array element

Postby kasuistry » Tue May 27, 2008 10:50 pm

Thanks for your kindly help, and I still have another problem.

Are the following two code segments equivalent?

Code: Select all
long long sum = 0;
int tid;

#pragma omp parallel default(shared) private(tid)
{
       tid = omp_get_thread_num();

       #pragma omp atomic
               sum += tid;
}


Code: Select all
long long sum = 0;
int tid;
omp_lock_t olock;
omp_init_lock(&olock);
#pragma omp parallel default(shared) private(tid)
{
       tid = omp_get_thread_num();

       omp_set_lock(&olock);
       #pragma omp flush(sum) /* 1st flush */
       sum += tid;
       #pragma omp flush(sum) /* 2nd flush */
       omp_unset_lock(&olock);
}
omp_destroy_lock(&olock);


Or rather I mean whether the atomic statement will both flush(read from memory to cache)
the involved shared variables before the statement and flush(write from cache to memory)
after the statement? If not, some inconsistence may occur. I can't find the solution from the
official manual since it says at a certain time only a thread have the right to modify a memory
space without interrupting from other threads. However, will it update its "temporary memory
view" before the modification and update the memory with its "temporary memory view" after
the modification?

By the way, the pure assignment "sum = tid" isn't allowed here. It's really inconvenient when
I want to assign a pointer with a new memory address.

Regards,
kasuistry
kasuistry
 

Re: flush an array element

Postby ejd » Wed May 28, 2008 5:15 am

If you look at the OpenMP V2.5 spec, section 2.7.4 atomic construct, it states:
The atomic construct ensures that a specific storage location is updated atomically, rather than exposing it to the possibility of multiple, simultaneous writing threads.

The idea being that it should do exactly what you want it to (i.e., the programs are equivalent). The wording is very specific - atomic "ensures that a specific storage location is updated atomically". Since it is talking about a "specific storage location" and not a "temporary view", the only way this can occur is if it loads from the storage location (meaning a flush before use) and stores back to the location after the update (flush after set).

As for the pure assignment, that is why I said depending on what you are trying to do (i.e., the format of the assignment), that atomic might work for you. Some compilers may allow the use of atomic for the pure assignment form - though it is not in conformance with the OpenMP spec.
ejd
 
Posts: 1025
Joined: Wed Jan 16, 2008 7:21 am

Re: flush an array element

Postby kasuistry » Wed May 28, 2008 7:42 am

Really thanks for your help. :D

Regards,
kasuistry
kasuistry
 

Re: flush an array element

Postby jakub » Wed Aug 13, 2008 11:34 pm

Up through the OpenMP V2.5 spec
? I can't find wording in OpenMP V3.0 spec that would allow subobjects in the flush list. The generic directive description documents list as a list of variable names (for C/C++) and flush directive description doesn't seem to talk about something other than variables.
jakub
 
Posts: 74
Joined: Fri Oct 26, 2007 3:19 am


Return to Using OpenMP

Who is online

Users browsing this forum: No registered users and 8 guests

cron