Этот вопрос относится к конструкции задачи в OpenMP 3.0 и ее использованию неявного firstprivate для C ++. Я ищу объяснение проблемы, а также возможные решения.
У меня была ошибка сегментации с программой, над которой я работал; Мне удалось свести проблему к следующему контрольному примеру.
Проблема возникает из-за того, что я обращаюсь к переменной экземпляра (объекта A) из #pragma omp task
#include <iostream>
#include <omp.h>
using namespace std;
class A {
private:
int someInstanceVariable;
public:
// This is never called
A(int _someInstanceVariable) {
someInstanceVariable = _someInstanceVariable;
}
A(const A& _A) {
cout << "Copy constructor called" << endl;
someInstanceVariable = _A.someInstanceVariable;
}
void simpleTask() {
// This task makes a reference to someInstanceVariable in the current object
#pragma omp task
{
// For access to stdout
#pragma omp critical
{
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// This line uses someInstanceVariable and causes a segfault
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
cout << "The value of the someInstanceVariable = " << someInstanceVariable << endl;
}
}
}
};
int main(int argc, char* argv[]) {
#pragma omp parallel
{
#pragma omp single
{
for(int i = 0; i < 10; i++) {
A* temp = new A(i);
temp->simpleTask();
}
}
}
return 0;
}
Когда я компилирую и запускаю программу с gcc 4.5 или выше (версия, которая поддерживает функцию задачи в OpenMP), т.е. gcc -fopenmp myprogram.cpp
, она работает нормально. Но когда я компилирую и запускаю программу с помощью компилятора Intel C ++ (версия, которая также поддерживает функцию задачи), то есть icpc -openmp myprogram.cpp
, она вызывает ошибки.
Выход GCC:
The value of the someInstanceVariable = 0
The value of the someInstanceVariable = 1
...
Вывод ICPC:
Segmentation fault
Я предполагаю, что хотя бы один из них должен быть не прав. Мои конкретные вопросы:
- В чем причина проблемы? Это потому, что я использую
someInstanceVariable
в #pragma omp task
, и это вызывает неявную первоприватную ссылку на указатель this?
- Еще лучше, может кто-нибудь указать мне на конкретный раздел в спецификации OpenMP 3.0 , который говорит об этом?
Я знаю, что могу решить проблему, создав локальную переменную
void simpleTask() {
// This task makes a reference to someInstanceVariable in the current object
#pragma omp task
{
int tempVariable = this -> someInstanceVariable;
// For access to stdout
#pragma omp critical
{
cout << "The value of the someInstanceVariable = " << tempVariable << endl;
}
}
}
Есть ли другие способы без создания временной переменной?