c++ threadインスタンスを無名にしてvectorに格納

マルチスレッドで、スレッドに名称をつけてスレッド数を管理するのは面倒です。

スレッド名を無名にして、vectorに格納しても同じ処理でのスレッド名に意味はないからその方が便利です。

#include <iostream>
#include <mutex>
#include <thread>
#include <vector>
#include <cmath>

std::mutex mtx_;                // mutex for exclusive control
std::vector vec{};         // prime numbers array
int cal_int = 1;                // calc target integer
int max_int = 10000000;         // calc target max number
std::vector threads;       // array of threads
int num_thread = 12;                    // number of threads



void add_prime(int i)           // store the prime numberns in the vector
{
    std::lock_guard lock(mtx_);
    vec.push_back(i);
}

int get_int()                   // get the integer to be tested
{
    std::lock_guard lock(mtx_);
    ++cal_int;
    if (cal_int > 2 && cal_int%2 == 0)      // do not return an even number larger than four
    {
        ++cal_int;
    }
    return cal_int;
}

void ThreadA()
{
    while (true)
    {
        bool flag = false;
        int i = get_int();
        if (i > max_int)
        {
            break;
        }
        int sqt = sqrt(i);
        for (int j = 2; j <= sqt; ++j)
        {
            if (i%j == 0)
            {
                flag = true;
                break;
            }
        }
        if (flag != true)
        {
            add_prime(i);
        }
    }
}

int main()
{
    std::chrono::system_clock::time_point  start, end;
    start = std::chrono::system_clock::now();

    std::cout << std::endl;
    std::cout << "Hardware concurrency = " << std::thread::hardware_concurrency() << std::endl;

    for(size_t i=0; i < num_thread; ++i){
        threads.emplace_back(std::thread(ThreadA));
    }

    for(auto& thread : threads){
        thread.join();
    }

    std::cout << std::endl;
    std::cout << "Number of threads = " << num_thread << std::endl;

    std::cout << std::endl;
    end = std::chrono::system_clock::now();
    double elapsed = std::chrono::duration_cast(end-start).count();
    std::cout << "elapsed time : " << elapsed << " ms" << std::endl;

    std::cout << std::endl;
    std::cout << "number of prime numbers : " << vec.size() << std::endl;

    std::cout << std::endl;
    std::cout << "last five prime numbers" << std::endl;
    std::sort(vec.begin(), vec.end() );
    
    for (auto itr = (vec.end() - 5); itr != vec.end(); ++itr)
    {
        std::cout << *itr << std::endl;
    }

}

こうすれば、変数を一箇所変えるだけでスレッド数が自由に変更できます。4以上の偶数は素数判定スレッドに渡さないで、処理時間短縮も図っています。

 

<実行結果>

Hardware concurrency = 12

Number of threads = 12

elapsed time : 1358 ms

number of prime numbers : 664579

last five prime numbers
9999937
9999943
9999971
9999973
9999991

https://isehara-3lv.sakura.ne.jp/blog/2022/05/01/c-マルチスレッドの効果/

で、およそ1.8秒でしたが1.3秒程度まで高速化。所詮、多数桁の素数計算には誤差とも言える範囲ですが。

 

admin

 

カテゴリーc++