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);
    }
  • 相关阅读:
    Apache Kafka:下一代分布式消息系统
    深入理解Java之线程池
    JAVA中线程同步的方法(7种)汇总
    String、StringBuffer与StringBuilder之间区别
    Java中是否可以继承String类,为什么
    JAVA4种线程池的使用
    一分钟教你知道乐观锁和悲观锁的区别
    java常见面试题及答案 11-20(JVM)
    springmvc中的页面解析器ViewResolver不起作用,变量输出字符串的解决方案
    SpringMVC默认欢迎页面的问题
  • 原文地址:https://www.cnblogs.com/wuOverflow/p/4935866.html
Copyright © 2011-2022 走看看