C++ OpenMP簡單介紹

一、背景知識

1、program作用

#pragma 是 C 和 C++ 語言中的一個預處理指令。它主要用於向編譯器發送特定的信息或者指示,以便控制編譯過程。#pragma 通常與編譯器特定的選項或功能一起使用,因此它的具體行為和實現可能因不同的編譯器而有所不同。

#pragma 的語法如下:

#pragma directive_name optional_arguments

其中,directive_name 是一個編譯器識別的指示名稱,optional_arguments 是可選的參數。

#pragma 的一些常見用途包括:

  • 優化:可以通過向編譯器提供優化建議來改善生成的代碼性能。例如,#pragma omp parallel for 用於 OpenMP 並行編程,以在循環中實現線程級並行。
  • 診斷:可以啟用或禁用特定的編譯器警告。例如,#pragma warning(disable: 4996) 可以在 Visual Studio 中禁用特定警告。
  • 代碼段:可以將代碼段駐留在特定的內存區域。例如,#pragma code_seg(“MY_SECTION”) 可以將代碼段放置在名為 “MY_SECTION” 的內存區域中。
  • 初始化和終止函數:可以指定在程序啟動和退出時自動執行的函數。例如,#pragma startup func1 和 #pragma exit func2 分別指定 func1 和 func2 在程序啟動和退出時執行。
  • 數據對齊:可以控制數據結構成員的對齊方式。例如,#pragma pack(push, 1) 和 #pragma pack(pop) 分別設置和恢復數據對齊方式。

由於 #pragma 可能因編譯器而異,建議查閱編譯器的文檔以瞭解支持的 #pragma 指令和相關功能。對於可移植性考慮,通常應盡量避免使用編譯器特定的 #pragma。

2、C++不同版本區別

C++ 有多個版本,其中比較常見的包括:

  • C++98/03:這是最初的 C++ 標準,也稱為 ISO/IEC 14882:1998(C++98),後來進行瞭一些小修訂,稱為 ISO/IEC 14882:2003(C++03)。該標準引入瞭類、繼承、多態、模板等面向對象編程特性。它還支持異常處理、RTTI(運行時類型識別)和 STL(標準模板庫)等功能。
  • C++11:也稱為 ISO/IEC 14882:2011。該標準在 C++98 的基礎上增加瞭大量新功能,如 lambda 表達式、右值引用、智能指針、constexpr 函數、nullptr 關鍵字、委托構造函數、變長模板等等。同時,它還對語言規范進行瞭一些修改和增強,以提高效率、可讀性和可維護性。
  • C++14:也稱為 ISO/IEC 14882:2014。該標準在 C++11 的基礎上進行瞭一些小修訂和改進。它主要增加瞭一些新特性,如二進制字面量、泛型 lambda 表達式、返回類型推導等。
  • C++17:也稱為 ISO/IEC 14882:2017。該標準在 C++14 的基礎上增加瞭許多新功能,如結構化綁定、內聯變量、if constexpr、折疊表達式等。它還對語言規范進行瞭大量修改和增強,以便提高效率、可讀性和可維護性。
  • C++20:也稱為 ISO/IEC 14882:2020。該標準在 C++17 的基礎上增加瞭許多新特性,如 concepts(概念)機制、三路比較運算符、協程、格式化 I/O 庫等等。同時,它還增強瞭現有的功能,並修復瞭一些缺陷和錯誤。

查看g++默認使用的C++版本

g++ -dM -E -x c++  /dev/null | grep -F __cplusplus

版本對照表

C++標準 __cplusplus值
C++ 11 201103L
C++ 14 201402L
C++ 17 201703L

指定不同版本編譯器

vim ~/.bashrc
echo alias g17=\'g++ -std=c++17\' >> ~/.bashrc
source ~/.bashrc

二、什麼是OpenMP

OpenMP 是一套 C++ 並行編程框架, 也支持 Forthan .
它是一個跨平臺的多線程實現, 能夠使串行代碼經過最小的改動自動轉化成並行的。具有廣泛的適應性。這個最小的改動,有時候隻是一行編譯原語!(在高階示例中,我們將演示並評估加速性能)
具體實現是通過分析編譯原語#pragma,將用原語定義的代碼塊,自動轉化成並行的線程去執行。每個線程都將分配一個獨立的id. 最後再合並線程結果。

OpenMP 共享內存的並行編程框架入門詳解

三、關鍵字

1、reduction 作用

在 OpenMP 中,reduction 用於將一個變量的值從多個線程中合並為單個結果。該指令提供瞭一個簡單的方法來實現並行計算中的歸約操作。
下面是 reduction 的語法示例:

#pragma omp parallel for reduction(+:sum)
for (i = 0; i < n; i++) {
    sum += a[i];
}

在這個例子中,我們使用瞭 + 運算符作為 reduction 操作符,並且要對變量 sum 進行歸約。在執行並行循環時,每個線程都會計算一部分的 sum 值,最終將這些值相加得到最終的結果。
其他的 reduction 操作符包括 -、*、&、|、^ 和 &&、||。可以根據具體應用場景選擇適當的操作符。
需要註意的是,被歸約的變量必須滿足以下條件之一:

  • 全局變量(全局作用域)
  • 靜態變量(靜態存儲期)
  • 分配在堆上的變量
  • 在 parallel 或 task region 中定義的私有變量

另外,OpenMP 還支持自定義數據類型的歸約操作,需要通過 omp declare reduction 指令來聲明自定義操作符和數據類型的歸約方式。

2、default(shared)作用

default(shared)是OpenMP的一個指令,用於指定在並行計算中所有變量都是共享的。這意味著變量的存儲將在所有線程之間共享,並且任何對變量的更改都將影響所有線程。使用此指令可以確保所有線程都使用相同的數據,因為它們都可以讀取和修改共享變量。

請註意,使用default(shared)可能會導致數據競爭和不一致的結果。因此,在使用並行計算時,必須小心謹慎地選擇變量的共享方式,並采取適當的同步措施來避免數據沖突。

到此這篇關於C++ OpenMP簡介的文章就介紹到這瞭,更多相關c++ OpenMP簡介內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: