zoukankan      html  css  js  c++  java
  • 并行却并不高效的 find

    template<typename Iterator, typename MatchType>
    Iterator parallelFind(Iterator first, Iterator last, MatchType match)
    {
        struct FindElement
        {
            void operator()(Iterator begin, Iterator end,
                            MatchType match,
                            std::promise<Iterator>* result,
                            std::atomic<bool>*      isFound)
            {
                try {
                    for (; begin != end; ++begin)
                    {
                        if (*begin == match)
                        {
                            result->set_value(begin);
                            isFound->store(true);
                            return;
                        }
                    }
                } catch (...) {
                    try {
                        result->set_exception(std::current_exception());
                        isFound->store(true);
                    } catch (...)
                    {}
                }
            }
        };
        
        size_t const length = std::distance(first, last);
        if (length == 0)
        {
            return last;
        }
        
        size_t constexpr minDataPerThread  = 25;
        size_t const     hardwareThreadNum = std::thread::hardware_concurrency();
        size_t const     neededThreadNum   =
            (length + minDataPerThread - 1) / minDataPerThread;
        size_t const     threadNum         = std::min(neededThreadNum,
                                                      hardwareThreadNum != 0
                                                      ? hardwareThreadNum
                                                      : 2);
        size_t const blockSize             = length / threadNum;
        std::vector<std::thread>       threads(threadNum - 1);
        std::atomic<bool>              isFound(false);
        std::promise<Iterator> result;
        {
            ThreadsJoiner joiner(threads);
            auto blockBegin = first;
            for (size_t i = 0; i < (threadNum - 1); ++i)
            {
                auto  blockEnd = blockBegin;
                std::advance(blockEnd, blockSize);
                threads[i] = std::thread(FindElement(),
                                         blockBegin, blockEnd, match,
                                         &result, &isFound);
                blockBegin = blockEnd;
            }
            
            FindElement()(blockBegin, last, match, &result, &isFound);
        }
        if (!isFound.load())
        {
            return last;
        }
        return result.get_future().get();
    }
    
    template <typename Iterator, typename MatchType>
    Iterator ImplParallelFind(Iterator first, Iterator last, MatchType match,
                              std::atomic<bool>& is_found)
    {
        try {
            size_t const            length              = std::distance(first, last);
            static size_t constexpr min_data_per_thread = 25;
            if (length < (2 * min_data_per_thread)){
                // If result has found, break.
                for (; (first != last) && (!is_found.load()); ++first){
                    if (*first == match){
                        is_found = true;
                        return first;
                    }
                }
                return last;
            }else{
                auto const mid_iterator = first + (length / 2);
                auto async_result =
                    std::async(&ImplParallelFind<Iterator, MatchType>,
                               mid_iterator, last, match, std::ref(is_found));
                auto const local_result = ImplParallelFind(first, mid_iterator,
                                                           match, is_found);
                return local_result == mid_iterator
                ? async_result.get()
                : local_result;
            }
        } catch (...) {
            is_found = true;
            throw;
        }
    }
    
    template <typename Iterator, typename MatchType>
    Iterator ParallelFind(Iterator first, Iterator last, MatchType match) {
        std::atomic<bool> is_found(false);
        return ImplParallelFind(first, last, match, is_found);
    }
  • 相关阅读:
    博客园设置自定义壁纸 模板
    html常用标签及属性,常用英语单词
    解释器安装与环境变量的添加
    计算机基础知识
    python 标准库大全
    进程的状态转换详解
    python 合集set,交集,并集,差集,对称差集别搞混
    vue组件,可以通过npm引用的组件
    use vue vuex vue-router, not use webpack
    Webpack+Vue如何导入Jquery和Jquery的第三方插件
  • 原文地址:https://www.cnblogs.com/wuOverflow/p/4935866.html
Copyright © 2011-2022 走看看