首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C和OpenMP:指向共享只读数据的指针会减慢执行速度。

C和OpenMP:指向共享只读数据的指针会减慢执行速度。
EN

Stack Overflow用户
提问于 2013-03-23 21:12:24
回答 2查看 2.8K关注 0票数 1

这是我的情况,我有一个指针数组指向一些数据数组.让我们说:

代码语言:javascript
复制
    Data** array = malloc ( 100 * sizeof(Data*));
    for(i = 0; i < 100; i++) array[i] = malloc (20 * sizeof(Data);

在并行区域中,我使用这些数据进行一些操作。例如:

代码语言:javascript
复制
    #pragma omp parallel num_threads(4) firstprivate(array)
    {
         function(array[0], array[omp_get_thread_num()];
    }

第一个参数是只读的,但在所有线程上都是相同的.

问题是,如果我使用一个不同的数据块(即: arrayomp_get_thread_num()+1 )作为第一个参数,那么每个函数都持续1seg。但是,当我使用相同的数据块数组时,每个函数调用都会持续4个use。

我的理论是,无法知道数组是否会被函数改变,因此每个线程都请求一个副本并使其他线程拥有的副本失效,这应该可以解释延迟的原因。

我试图像这样在本地复制数组:

代码语言:javascript
复制
    #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)

EN

回答 2

Stack Overflow用户

发布于 2013-03-23 22:56:39

我认为您的分析是正确的,编译器无法知道在他的背后指向数组并没有改变。实际上,他知道它们可能会改变,因为线程0作为可修改的参数也接收相同的array[0]

所以他必须经常重新加载这些值。首先,您应该声明如下所示的函数

代码语言:javascript
复制
void function(Data const*restrict A, Data*restrict B);

这首先告诉编译器,A中的值不能更改,然后任何指针都不能由其他指针(或任何其他指针)别名,这样他就知道数组中的值只会由函数本身改变。

对于线程号0,上面的断言将不是真,数组AB实际上是相同的。因此,最好在进入array[0]之前将temparray复制到公共#pragma omp parallel中,并将相同的temparray作为第一个参数传递给每个线程:

代码语言:javascript
复制
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()];
票数 2
EN

Stack Overflow用户

发布于 2017-07-07 09:39:30

我认为你的分析是错误的。如果数据不被更改,imho将不会在内核之间同步。这一放缓有两个可能的原因。

  1. 核心#0获得function(array[0], array[0])。你说过第一个参数是只读的,但第二个不是。因此,核心#0将改变array[0]中的数据,并且CPU必须始终在内核之间同步这些数据。
  2. 第二个可能的原因是数组的大小很小(20个元素)。发生的情况是,核心#1得到一个指向20元素数组的指针,而核心#2得到指向数组的指针,这可能就在内存中的数组#1之后。因此,它们很有可能位于同一条高速缓存线上。CPU不跟踪每个特定元素的更改--如果它看到同一高速缓存线上的元素被更改,它将同步内核之间的缓存。解决方案是使每个数组更大(这样,在20个元素之后,就有相当于缓存大小(128 K?256 k?)的未使用空间)。

我猜您的代码中同时存在#1和#2的问题。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15592124

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档