OpenMP: how to flush pointer target?

倖福魔咒の 提交于 2019-12-05 02:57:17

问题


I’ve just noticed that the following code doesn’t compile in OpenMP (under GCC 4.5.1):

struct job {
    unsigned busy_children;
};

job* j = allocateJob(…);
// …

#pragma omp flush(j->busy_children)

The compiler complains about the -> in the argument list to flush, and according to the OpenMP specification it’s right: flush expects as arguments a list of “id-expression”s, which basically means only (qualified) IDs are allowed, no expressions.

Furthermore, the spec says this about flush and pointers:

If a pointer is present in the list, the pointer itself is flushed, not the memory block to which the pointer refers.

Of course. However, since OpenMP also doesn’t allow me to dereference the pointers I basically cannot flush a pointee (pointer target).

– So what about references? The spec doesn’t mention them but I’m not confident that the following is conformant, and will actually flush the pointee.

unsigned& busy_children = j->busy_children;
#pragma omp flush(busy_children)

Is this guaranteed to work?

If not, how can I flush a pointee?


回答1:


The flush directive has given the OpenMP ARB a headache for a long time. So much so, that there has been talk about removing it completely - though that creates other problems. Using flush(list), is extremely difficult to get correct and even the OpenMP experts have a great deal of trouble getting it correct. The problem with it, is that the way it is defined it can be moved around in your code by the compiler. That means that you should stay away from using flush(list).

As for your question about being able to flush a pointee, there is only one way to do that and that is to use flush (without a list). This will flush your entire thread environment and as such, can not be moved by the compiler. It seems "heavy handed", but the compilers are actually pretty good about flushing what is necessary when using flush without a list.




回答2:


OpenMP specification doesn't directly says about the type of a variable, but MSDN says that "A variable specified in a flush directive must not have a reference type". This make me think that this is not guaranteed to work. The flush directive with empty variable list should flush all memory so this is what you can safely use.




回答3:


The reason you cannot flush a dereferenced pointer is because flush is only needed for values in hardware registers. There is never any need under OpenMP to flush something that is NOT in a hardware register (for example, in cache or memory), since OpenMP assumes a coherent cache memory that guarantees that all threads will always see the same value when the same address is dereferenced. Hardware protocols guarantee cache coherency, making the multiple local caches behave like one shared global cache.



来源:https://stackoverflow.com/questions/4821491/openmp-how-to-flush-pointer-target

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!