这是我的情况,我有一个指针数组指向一些数据数组.让我们说:
Data** array = malloc ( 100 * sizeof(Data*));
for(i = 0; i < 100; i++) array[i] = malloc (20 * sizeof(Data);在并行区域中,我使用这些数据进行一些操作。例如:
#pragma omp parallel num_threads(4) firstprivate(array)
{
function(array[0], array[omp_get_thread_num()];
}第一个参数是只读的,但在所有线程上都是相同的.
问题是,如果我使用一个不同的数据块(即: arrayomp_get_thread_num()+1 )作为第一个参数,那么每个函数都持续1seg。但是,当我使用相同的数据块数组时,每个函数调用都会持续4个use。
我的理论是,无法知道数组是否会被函数改变,因此每个线程都请求一个副本并使其他线程拥有的副本失效,这应该可以解释延迟的原因。
我试图像这样在本地复制数组:
#pragma omp parallel num_threads(4) firstprivate(array)
{
Data* tempData = malloc(20 * sizeof(Data));
memcpy(tempData,array[0], 20*sizeof(Data));
function(tempData, array[omp_get_thread_num()];
}但我得到了同样的结果..。就像线程没有“释放”数据块,所以其他线程可以使用它.
我必须指出,第一个参数并不总是数组,所以我不能在语用行中使用first私有(数组).
问题如下:
很难让我明白,所以如果你需要更多的信息,请告诉我!
提前谢谢..。哈维尔
编辑:我不能更改函数声明,因为它在库中!(ACML)
发布于 2013-03-23 22:56:39
我认为您的分析是正确的,编译器无法知道在他的背后指向数组并没有改变。实际上,他知道它们可能会改变,因为线程0作为可修改的参数也接收相同的array[0]。
所以他必须经常重新加载这些值。首先,您应该声明如下所示的函数
void function(Data const*restrict A, Data*restrict B);这首先告诉编译器,A中的值不能更改,然后任何指针都不能由其他指针(或任何其他指针)别名,这样他就知道数组中的值只会由函数本身改变。
对于线程号0,上面的断言将不是真,数组A和B实际上是相同的。因此,最好在进入array[0]之前将temparray复制到公共#pragma omp parallel中,并将相同的temparray作为第一个参数传递给每个线程:
Data const* tempData = memcpy(malloc(20 * sizeof(Data)), array[0], 20*sizeof(Data));
#pragma omp parallel num_threads(4)
function(tempData, array[omp_get_thread_num()];发布于 2017-07-07 09:39:30
我认为你的分析是错误的。如果数据不被更改,imho将不会在内核之间同步。这一放缓有两个可能的原因。
function(array[0], array[0])。你说过第一个参数是只读的,但第二个不是。因此,核心#0将改变array[0]中的数据,并且CPU必须始终在内核之间同步这些数据。我猜您的代码中同时存在#1和#2的问题。
https://stackoverflow.com/questions/15592124
复制相似问题