当前位置:   article > 正文

C++使用std::thread 多线程展开for循环,for循环并行计算_#pragma omp parallel for num_threads(num_threads_)

#pragma omp parallel for num_threads(num_threads_) schedule(guided, 8)
  • 比如说有一个for循环,需要迭代100次,来累加1+2+3…+100计算其结果,创建10个线程,第一个线程累加1+2+…+10,第二个线程计算11+12+…+20等。那么如何优化呢?
  • 其实OpenMP库是可以直接调用的,只需要在for循环上面加一个指令 “#pragma omp parallel for num_threads(10)” 即可,非常简单。
  • Intel TBB 线程库也可以很简单的做到,具体不介绍
  • 下面介绍如何使用标准库std::thread手动分割任务 。如果任务数除以线程数有余数,那么把这些余数的部分放在最后一个线程上。
#include <iostream>
#include <thread>
#include <vector>
#include <atomic>
#include <tbb/task_arena.h>

using namespace std;

constexpr int THREAD_NUM = 10; 

atomic<int> a(0);

void test(int b) {
    int expected = a;
    // 使用了CAS
    while (!atomic_compare_exchange_weak(&a, &expected, a + b));
}

int main() {
    vector<thread> threads;
    threads.reserve(static_cast<size_t>(THREAD_NUM));

    // 假如有任务数为 100 个(编号为0,1,...,99), 平分到10个线程上去,每个线程执行10个任务
    int TASK_NUM = 100;
    int AVG_NUM = TASK_NUM / THREAD_NUM;
    
    for (int i = 0; i < THREAD_NUM - 1; ++i) {
        threads.emplace_back([i, AVG_NUM](){
            for (int j = i * AVG_NUM; j < (i + 1) * AVG_NUM; j++) {
                test(j + 1);
            }
        });
    }
    threads.emplace_back([&](){
        for (int j = (THREAD_NUM - 1) * AVG_NUM; j < TASK_NUM; j++) {
            test(j + 1);
        }
    });


    for (auto &t : threads) {
        t.join();
    }
    cout << "a = " << a << endl;
    // 计算结果为5050,计算正确
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/275962
推荐阅读
相关标签
  

闽ICP备14008679号