LoginSignup
3
1

Mac標準のclangがParallel STLをサポートしていない(2024年1月現在)

表題の通りです。macos Sonoma 14.2.1及びXCode 15.2、Clangのバージョンは15.0.0です。

次のようなParallel STLの計測プログラムを書いてみたのですが、

performance_comparison.cpp
#include <algorithm>
#include <execution>
#include <chrono>
#include <vector>
#include <iostream>
#include <random>

int main() {
    // ベクターのサイズ
    const size_t dataSize = 1000000;

    // テストデータの生成
    std::vector<int> data(dataSize);
    std::generate(data.begin(), data.end(), std::rand);

    // Parallel STLを使用しない場合の計測
    auto dataCopy = data;
    auto start = std::chrono::high_resolution_clock::now();
    std::sort(dataCopy.begin(), dataCopy.end());
    auto end = std::chrono::high_resolution_clock::now();
    std::chrono::duration<double> elapsed = end - start;
    std::cout << "通常のSTLの実行時間: " << elapsed.count() << " 秒" << std::endl;

    // Parallel STLを使用する場合の計測
    start = std::chrono::high_resolution_clock::now();
    std::sort(std::execution::par, data.begin(), data.end());
    end = std::chrono::high_resolution_clock::now();
    elapsed = end - start;
    std::cout << "Parallel STLの実行時間: " << elapsed.count() << " 秒" << std::endl;

    return 0;
}

std::executionなんてないとか言われますね。ご無体な……。

image.png

LLVMプロジェクトからParallel STLの実装をとってくる

仕方がないので、LLVMプロジェクトからpstl(Paralell STL)の実装を取ってきます。

上記ディレクトリをDownloadして、上記.cppファイルの隣に配置します。

そして、CMakeLists.txtも追加します。

cmake_minimum_required(VERSION 3.13)
project(app)
set(CMAKE_C_STANDARD 17)
set(CMAKE_CXX_STANDARD 23)

add_subdirectory(pstl)

add_executable(app "performance_comparison.cpp")

target_link_libraries(app PRIVATE ParallelSTL)

add_subdirectoryで先ほど配置したpstlディレクトリを指定します。

ヘッダファイルの書き換え

実装を置き換えるために、algorithmとexecutionのヘッダファイルを置き換えます。

performance_comparison.cpp
// #include <algorithm>
// #include <execution>
#include "pstl/include/__pstl_algorithm"
#include "pstl/include/__pstl_execution"
#include <chrono>
#include <vector>
#include <iostream>
#include <random>
...

cmakeとmakeを実行します。

image.png

image.png

さて、実行してみましょう。

image.png

あ、あれ? Parallel STL版の方が遅い?
実は、標準ではシリアル実行になっていて、全く速くなりません。
バックエンドにOpenMPかTBBを指定できるようになっています。それらを指定しないと速くならないのですね。

TBBをバックエンドに指定する

OpenMPの方は色々試しましたがうまくいかなかったので、TBBを利用することにします。

homebrewでTBBをインストールします。

$ brew install tbb

CMakeでPSTL_PARALLEL_BACKENDtbbに指定します

cmake_minimum_required(VERSION 3.13)
project(app)
set(CMAKE_C_STANDARD 17)
set(CMAKE_CXX_STANDARD 23)

set(PSTL_PARALLEL_BACKEND tbb) # ←追加

add_subdirectory(pstl)

add_executable(app "performance_comparison.cpp")

target_link_libraries(app PRIVATE ParallelSTL)

CMakeを実行すると、TBBをバックエンドに使う旨が表示されます。

image.png

makeして実行すると……

image.png

速くなってますね。2倍程度だとちょっと物足りないけど。もう少し大きいサンプルでも試してみたいところです。

最後に

LLVMプロジェクトのpstl実装を利用することで、現行のMacでもParallel STLが使えることを確認できました。
READMEを見る限り、まだ制約も多いようなので個人的にはあくまで練習用に使うつもりですが、この記事がお役に立てれば幸いです。

そして、LLVMのpstlの存在を教えてくれたMehmet Oguz Derinさんに感謝します。

3
1
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1