![](/img/trans.png)
[英]openMP lastprivate and firstprivate to the same variable
[英]Segmentation fault when accessing a instance variable (implicit firstprivate) through Openmp task
這個問題特定於 OpenMP 3.0 中的任務構造及其對 C++ 的隱式 firstprivate 的使用。 我正在尋找問題的解釋以及可能的解決方案。
我正在處理的程序有一些分段錯誤; 我設法將問題減少到以下測試用例。
出現問題是因為我正在從#pragma omp task
中訪問實例變量(object A)
#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
)編譯和運行程序時,它運行良好。 但是當我使用英特爾的 C++ 編譯器(也支持任務功能的版本)編譯和運行程序時,即icpc -openmp myprogram.cpp
它出現了段錯誤。
GCC 的 output:
The value of the someInstanceVariable = 0
The value of the someInstanceVariable = 1
...
ICPC的output:
Segmentation fault
我假設其中至少有一個是錯誤的。 我的具體問題:
#pragma omp task
中使用了someInstanceVariable
並且它導致了對 this 指針的隱式 firstprivate 引用嗎?我知道我可以通過創建局部變量來解決問題
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; } } }
有沒有其他方法不創建臨時變量?
這是 OpenMP 的痛苦問題之一。 由於 OpenMP 不是基本語言 (C/C++) 的一部分,因此 OpenMP 難以處理 class 對象。 原因是 object 在 OpenMP“附加組件”看到 object 時可能未實例化。 在某些情況下可以做到這一點,但到目前為止,OpenMP 規范已經決定最好不要嘗試處理對象的任何情況。 這就是為什么,如果您閱讀 OpenMP 規范,它指的是變量。 變量在基礎語言中有一個非常具體的定義。
Firstprivate 處理變量而不是 class 對象。 英特爾編譯器不會使 class object 成為第一個私有的,因此當您嘗試打印 someInstanceVaribale 的值時,大多數情況下您會遇到段錯誤(因為它的地址為零,因為它是共享的並且已經消失超出范圍)。 似乎 g++ 所做的比 OpenMP 規范所要求的要多。 在任何情況下,如果您創建指向 class object 的指針,則該指針可以設為 firstprivate,並將從任務中指向正確的 object。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.