并行但并不十分高效的 for_each 实现

class ThreadsJoiner
{
    std::vector<std::thread>& threads;
public:
    ThreadsJoiner(std::vector<std::thread>& threads_):
        threads(threads_)
    {}

    ~ThreadsJoiner()
    {
        for (auto& thread : threads)
        {
            if (thread.joinable())
            {
                thread.join();
            }
        }
    }
};

template<typename Iterator, typename Func>
void parallelForEach(Iterator first, Iterator last, Func f)
{
    size_t const length            = std::distance(first, last);
    if (length < 0)
    {
        return;
    }

    size_t constexpr minDataPerThread  = 25;
    size_t const     hardwareThreadNum = std::thread::hardware_concurrency();
    size_t const     maxThreadNum      =
        (length + minDataPerThread - 1) / minDataPerThread;
    size_t const     threadNum         = std::min(maxThreadNum,
                                                  hardwareThreadNum == 0
                                                  ? 2
                                                  : hardwareThreadNum);
    size_t const blockSize = length / threadNum;
    std::vector<std::future<void>> futures(threadNum - 1);
    std::vector<std::thread>       threads(threadNum - 1);
    ThreadsJoiner joiner(threads);

    auto blockBegin = first;
    for (size_t i = 0; i < (threadNum - 1); ++i)
    {
        auto blockEnd = blockBegin;
        std::advance(blockEnd, blockSize);
        std::packaged_task<void(void)> task([=]{std::for_each(blockBegin,
                                                              blockEnd, f);});
        futures[i] = task.get_future();
        threads[i] = std::thread(std::move(task));
        blockBegin = blockEnd;
    }

    std::for_each(blockBegin, last, f);
    for (auto& future : futures)
    {
        future.get();
    }
}

template<typename Iterator, typename Func>
void parallelForEach(Iterator first, Iterator last, Func f)
{
    size_t const            length   = std::distance(first, last);
    if (length == 0)
    {
        return;
    }
    static constexpr size_t thunkSize = 25;
    if (length <= thunkSize)
    {
        std::for_each(first, last, f);
    }
    else
    {
        auto midIt  = first + length / 2;
        auto firstHalf = std::async(&parallelForEach<Iterator, Func>,
                                 first, midIt, f);
        parallelForEach(midIt, last, f);
        firstHalf.get();
    }
}
时间: 2024-12-16 15:49:55

并行但并不十分高效的 for_each 实现的相关文章

2017年&quot;程序媛和工程狮&quot;绝对不能忽视的编程语言、框架和工具

2017年"程序媛和工程狮"绝对不能忽视的编程语言.框架和工具 IT程序狮· 9 天前 在过去的一年里,软件开发行业继续大踏步地向前迈进.回顾 2016 年,我们看到了更多新兴的流行语言.框架和工具,它们改变着我们的工作方式,让我们看到更多的可能.但在这个行业,紧随潮流是很难的.所以在每年年底,我们都会给你提供一些建议,它涉及什么是最重要的,以及你在未来一年中应该学习什么. 大趋势 渐进式 Web Apps 在 2016 年里,我们见证了 Progressive Web App 概念的

2017 年你应该学习的编程语言、框架和工具

摘要: 2016 年在开发者圈子中许多新的技术和概念层出不穷,人工智能.机器学习.Progressive Web Apps 等等,各种语言.框架和工具的更新也是让人看得眼花缭乱.2017 年,作为开发者应该跟随潮流还是理性选择新技术? 软件开发行业继续向前大步迈进. 在 2016 年,我们看到了很多新版本的流行语言.框架和工具.它给了我们更多的支持,也改变了我们的工作方式.紧跟潮流是很难的,所以在每年年底,我们会给你介绍什么是重要的,而且应该在未来十二个月内学习. 一.趋势 Progressiv

并发编程简介

与串行程序开发相比,并发编程的难度更大,编写.调试.维护都很困难,导致很多开发人员图省事放弃并发编程.但是现在已经进入了多核移动互联时代,现在连入门级的手机都是多核的,所以如何充分发挥多核处理器系统的强大的计算能力,是我们每个开发人员需要面对的. 一.并发的历史 1.串行时代 串行执行的特点 每次只能运行一个程序,只有其执行完成其他程序才能开始执行. 这种方式人类流水线的工作方式,其优势在于直观性和简单性. 串行执行的缺点 资源利用率低,单个程序执行不能有效率用cpu资源,尤其是其进行长时间IO

Android--开发:由模块化到组件化

在Android SDK一文中,我们谈到模块化和组件化,现在我们来聊聊组件化开发背后的哪些事.最早是在广告SDK中应用组件化,但是同样适用于普通应用开发 以下高能,请做好心理准备,看不懂请发私信来交流.本文不推荐新手阅读,如果你刚接触Android开发不久,请立刻放弃阅读本文. 模块化和组件化 模块化 组件化不是个新概念,其在各行各业都一直备受重视.至于组件化什么时候在软件工程领域提出已经无从考究了,不过呢可以确认的是组件化最早应用于服务端开发,后来在该思想的指导下,前端开发和移动端开发也产生各

Android 开发:由模块化到组件化(一)

模块化和组件化 模块化 组件化不是个新概念,其在各行各业都一直备受重视.至于组件化什么时候在软件工程领域提出已经无从考究了,不过呢可以确认的是组件化最早应用于服务端开发,后来在该思想的指导下,前端开发和移动端开发也产生各自的开发方式. 在了解组件化之前,先来回顾下模块化的定义 Modular programming is a software design technique that emphasizes separating the functionality of a program in

2017 年应该学习的编程语言、框架和工具

在过去的一年里,软件开发行业继续大踏步地向前迈进.回顾 2016 年,我们看到了更多新兴的流行语言.框架和工具,它们改变着我们的工作方式,让我们看到更多的可能.但在这个行业,紧随潮流是很难的.所以在每年年底,我们都会给你提供一些建议,它涉及什么是最重要的,以及你在未来一年中应该学习什么.大趋势 渐进式 Web Apps在 2016 年里,我们见证了 Progressive Web App 概念的蓬勃兴起.它意味着 Web 应用程序可以离线工作,并能提供原生移动应用的体验.它们可以添加到你的智能设

2017 年该学习的编程语言、框架和工具

转:http://top.jobbole.com/35926/?utm_source=blog.jobbole.com&utm_medium=sidebar-top-news 软件开发行业继续向前大步迈进. 在 2016 年,我们看到了很多新版本的流行语言.框架和工具.它给了我们更多的支持,也改变了我们的工作方式.紧跟潮流是很难的,所以在每年年底,我们会给你介绍什么是重要的,而且应该在未来十二个月内学习. 一.趋势 Progressive Web Apps 在 2016 年,我们看到了 Prog

深度学习“引擎”之争:GPU加速还是专属神经网络芯片?

深度学习“引擎”之争:GPU加速还是专属神经网络芯片? 深度学习(Deep Learning)在这两年风靡全球,大数据和高性能计算平台的推动作用功不可没,可谓深度学习的“燃料”和“引擎”,GPU则是引擎的引擎,基本所有的深度学习计算平台都采用GPU加速.同时,深度学习已成为GPU提供商NVIDIA的一个新的战略方向,以及3月份的GTC 2015的绝对主角. 那么,GPU用于深度学习的最新进展如何?这些进展对深度学习框架有哪些影响?深度学习开发者应该如何发挥GPU的潜力?GPU与深度学习结合的前景

SQL Server SQL性能优化之--通过拆分SQL提高执行效率,以及性能高低背后的原因

复杂SQL拆分优化 拆分SQL是性能优化一种非常有效的方法之一, 具体就是将复杂的SQL按照一定的逻辑逐步分解成简单的SQL,借助临时表,最后执行一个等价的逻辑,已达到高效执行的目的 一直想写一遍通过拆分SQL来优化的博文,最近刚好遇到一个实际案例,比较有代表性,现分享出来, 我们来通过一个案例来分析,为什么拆分语句可以提高SQL执行效率,更重要的是弄清楚,拆分前为什么慢,拆分后为什么快了? 幼稚的话,各位看官莫笑 先看一下相关表的数据量,大表也有5900多万,小表有160多万 (声明:我从来没