【问题标题】:OpenMP named critical section: if a program variable is used, is it evaluated or is it used as string without being evaluated?OpenMP 命名临界区:如果使用程序变量,是对其进行评估还是将其用作字符串而不进行评估?
【发布时间】:2020-06-19 15:27:38
【问题描述】:

我有以下代码,我想将 omp 添加到:

for ( int i = 0 ; i < N ; i++ ) {
    double max2 = 0.; 
    (calculate max2);

    for ( int j = 0 ; j < 3 ; j++) {
        int m = group[i].member[j];
        if ( members[m].norm < max2 ) {
            members[m].norm = max2; 
        }
    }
}

需要保护对成员的访问,但我想使用命名的关键部分,以避免有效序列化该循环的速度损失。我想做的是这样的:

#pragma omp parallel for
for ( int i = 0 ; i < N ; i++ ) {
    double max2 = 0.; 
    (calculate max2);

    for ( int j = 0 ; j < 3 ; j++) {
        int m = group[i].member[j];
#pragma omp critical (m)
        if ( members[m].norm < max2 ) {
            members[m].norm = max2; 
        }
    }
}

这样只有真正写入相同 m 值的线程才会相互等待。我的问题是:“m”是用作关键名称的字符串,还是实际评估并将其值用作关键部分的名称?它确实可以编译,但我不知道它是否按照我认为的那样做。如果有人能澄清 omp 在这里做了什么(例如 omp 如何实现这些),我将不胜感激。

非常感谢*。

【问题讨论】:

    标签: synchronization openmp thread-synchronization critical-section


    【解决方案1】:

    critical 的名称必须是编译时常量。但这不是一个字符串或其他东西,它只是一个放在括号中的名称,例如

    #pragma omp critical (foo)

    对于您的模式,您将不得不使用锁,类似于:

    #pragma omp parallel for
    for ( int i = 0 ; i < N ; i++ ) {
        double max2 = 0.; 
        (calculate max2);
    
        for ( int j = 0 ; j < 3 ; j++) {
            omp_lock_t * lck = group[i].member[j].my_lock;
            omp_set_lock(*lck);
            if ( members[m].norm < max2 ) {
                members[m].norm = max2; 
            }
            omp_unset_lock(*lck);
        }
    }
    

    请注意,OpenMP 中的锁必须被初始化。请参阅https://www.openmp.org/spec-html/5.0/openmpse31.html#x191-9120003.3 了解更多信息。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-26
      • 1970-01-01
      • 2020-06-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多