Именованный критический раздел OpenMP: если используется программная переменная, оценивается ли она или используется как строка без оценки? - PullRequest
1 голос
/ 19 июня 2020

У меня есть следующий фрагмент кода, для которого я хочу добавить 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; 
        }
    }
}

Доступ к членам должен быть защищен, но я хотел бы использовать именованный критический раздел, чтобы избежать потеря скорости эффективной сериализации этого l oop. Я хочу сделать следующее:

#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 это реализует).

Большое спасибо.

1 Ответ

1 голос
/ 19 июня 2020

Имя 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 .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...