• 通过打包 accumulate 实现多线程版本的 accumulate


    #include <iostream>
    #include <algorithm>
    #include <thread>
    #include <functional>
    
    using namespace std;
    
    template <typename Iterator, typename T>
    struct accumulate_block
    {
      void operator ()(Iterator first, Iterator last, T &result)
      {
        result = accumulate(first, last, result);
      }
    };
    
    template <typename Iterator, typename T>
    T parallel_accumulate(Iterator first, Iterator last, T init)
    {
        unsigned long const length = std::distance(first, last);
    
    //if there is no element, return init value
        if(!length){
            return init;
        }
    
    
        unsigned long const min_per_thread = 25;
    
        //how much threads at least we needed
        unsigned long const max_threads =
            (length + min_per_thread - 1) / min_per_thread;
    
        unsigned long const hardware_threads =
            std::thread::hardware_concurrency();
    
    //if max_threads more than hardware threads,
    //just use hardware threads
    //if hardware threads not support even muiltithreads, use 2 threads
    //instead of , use hardware threads
        unsigned long const num_threads =
            std::min( hardware_threads != 0
                                                             ? hardware_threads
                                                             :  2
                         , max_threads);
    
        //the length of the range was divided by threads
        unsigned long const block_size = length / num_threads;
    
        std::vector<T>                 results  (num_threads);
        std::vector<std::thread>  threads (num_threads - 1);
    
        auto block_start = first;
        for(unsigned long i = 0; i < (num_threads - 1); ++i){
            auto block_end = block_start;
            
            //put block_end to the end of current block
            std::advance(block_end, block_size);
            
            threads[i] = std::thread(
                  accumulate_block<Iterator, T>(),
                  block_start, block_end, std::ref(results[i]));
            block_start = block_end;
        }
            accumulate_block<Iterator, T>()(block_start,
                                             last,
                                             results[num_threads - 1]);
            std::for_each(threads.begin(), threads.end(),
                                     std::mem_fn(&std::thread::join));
    
            return std::accumulate(results.begin(), results.end(), init);
    }
    
    int main()
    {
        vector<int> ivec{1, 2, 3, 4, 5, 5, 6, 7, 8, 9};
        int result = 0;
        result = parallel_accumulate(ivec.cbegin(), ivec.cend(), result);
        cout << result << endl;
        return 0;
    }
  • 相关阅读:
    Amoeba for MySQL读写分离配置
    基于amoeba实现mysql数据库的读写分离/负载均衡
    Amoeba实现mysql主从读写分离
    OpenERP 的XML-RPC的轻度体验+many2many,one2many,many2one创建方式
    openerp用wizard导入excel数据
    OpenERP在product中增加外部网络链接图片
    OpenERP7.0安装后提示“not supported" ,如何去掉此提示
    windows命令行设置IP与DNS
    ubuntu开机自动启动xampp/lampp的两种方法
    [Python]网络爬虫(五):urllib2的使用细节与抓站技巧
  • 原文地址:https://www.cnblogs.com/wuOverflow/p/4295566.html
Copyright © 2020-2023  润新知