C++并发编程(十)并行算法函数

C++多线程并行计算 C++多线程并行计算多线程(std::thread) 多线程(std::thread) 写了一个简短的并行计算例子 存粹的利用CPU性能计算素数个数 //实现标准库头文件<numeric>中accumulate函数的并行版本 #include <iostream> #include <thread> #include <numeric> #inclu... 阅读详情

本章主要介绍C++17标准的并行算法函数。

目录

1.并行化的标准库算法函数

2.执行策略

2.1执行策略普遍产生的作用

2.2std::execution::sequenced_policy

2.3std::execution::parallel_policy

2.4std::execution::parallel_unsequenced_policy

3.C++标准库的并行算法函数

3.1并行算法函数使用范例

3.2访问计数


1.并行化的标准库算法函数

C++17向标准库加入了并行算法函数,它们是多个函数的重载,如“std::fiind()、std::transform()和std::reduce()”,其操作的目标都是容器区间,相比对应的单线程版本,并行版本具有相同的函数签名,只是新增了一个参数,该参数排在参数列表的第一位,用于设定执行策略:

std::vector<int> my_data;
std::sort(std::execution::par, my_data.begin(), my_data.end());

通过执行策略std::execution::par,准许该调用采用多线程,按并行算法执行。标准库可以自行决定调用方式。

2.执行策略

C++17标准制定了3种执行策略,由头文件<execution>定义:
std::execution::sequenced_policy
std::execution::parallel_policy
std::execution::parallel_unsequenced_policy

该头文件还定义了三个对应的策略对象,作为参数向算法函数传递:
std::execution::seq
std::execution::par
std::execution::par_unseq

根据C++标准,任何程序库的实现都可以提供额外的执行策略,并自行决定该执行策略的语义。

2.1执行策略普遍产生的作用

向标准库算法函数传入执行策略参数,函数行为受控于该策略的影响:
算法复杂度、执行异常的行为、算法函数步骤的执行方式、对复杂度产生的作用

因为并行执行需要进行额外的调度管理、执行更多核心操作(内部数据互换、执行比较操作或运行函数对象),意在减少总运行时间。

复杂度变化的精确细节因不同算法函数而异,假设某算法一个行为的重复数为SE,若采用指定的执行策略,其复杂度要求则放宽到O(SE),也就是前者操作量的数倍,增长的倍数取决于标准库的内部实现和系统平台的底层实现。

1.异常行为

假设调用某算法函数期间有异常抛出,则后果取决于所选用的执行策略。若异常未被捕获,在执行C++标准的三种执行策略的情况下,会调用std::terminate()令整个程序终止;若按标准的执行策略执行,则抛出的异常只有std::bad_alloc异常(无法分配足够的内存资源)。

2.算法中间步骤的执行主体和执行时机

执行策略的基本要素,也是不同策略之间的不同点。执行策略指定了算法函数中间步骤的执行主体,可能是CPU线程、定向流、GPU线程或其他运算单元。也指定了算法中间步骤的内存次序约束:这些独立的步骤是否可交错执行或并行执行等。

2.2std::execution::sequenced_policy

顺序策略,令算法函数在调用的线程上执行,因而不会发生并行,也不存在交错执行。若某算法函数的重载按指定执行策略执行,与没有指定执行策略相比,两者服从的内存次序可能有差异(没有指定执行策略则按顺序执行)。

std::execution::sequenced_policy几乎没有施加内存次序限制,可自由选择同步机制。

2.3std::execution::parallel_policy

并行策略,给出了多个线程并行的基本模式。函数的内部操作可以在发起调用的线程上执行,也可以由程序库另外创建线程执行。

并行策略对内存次序施加了更多限制:绝不能引发数据竞争,不能假设任何操作由同一线程执行,也不得假设其他任何操作由别的线程执行。

在绝大多数情况下,都可以采用并行策略,只有下述情况会引发问题:

std::vector<int> v;
int count = 0;
std::for_each(std::execution::par, v.begin(), v.end(), [&](int& x) {x = ++count; });

上述函数迭代更新容器v中的元素,lambda函数每次更新都调用count,若在多个线程上同时执行该函数,会导致数据竞争,因为前面发生的函数调用会影响其后调用的运行,诱发未定义行为。

并行策略允许函数调用间的同步操作,我们可以将count原子化为std::atomic<int>,或采用互斥保护,虽然违背并行策略初衷,但能让多个调用同步访问共享数据。

2.4std::execution::parallel_unsequenced_policy

非顺序并行策略,就其内存次序施加了最严格的限制,以便标准库最大限度地发挥算法并行化的潜力。采用该执行策略的算法函数会在单个或多个线程上按乱序执行算法步骤,线程间的操作将不服从代码流程的先后顺序。
例如:第二项操作在第一项操作之前执行;某操作在第一个线程上启动,第二个线程上执行一部分,在第三个线程上收尾。

在不同迭代器、值或可调用对象上的操作不可以任何形式同步,也不能与别的函数或代码同步,即内部操作不能更改线程之间的共享数据或元素之间的共享状态。

3.C++标准库的并行算法函数

算法函数由头文件<algorithm>和<numeric>给出。

需要注意:若函数内部操作不满足结合律和交换律,由于操作次序不明确,可能导致结果不稳定。

是否支持执行策略,不仅令函数签名产生区别,其参数类型也有影响:若普通函数接收输入、输出迭代器,则其接收执行策略的重载只接受前向迭代器。因为输入、输出迭代器本质上是单通(single-pass)迭代器:只能通过它访问当前位置的元素,而不能将它逆转到或访问以往位置的元素。

C++迭代器类别

迭代器具有继承关系(单通为基类)

单通迭代器:

1.输入迭代器:

       用于读取容器中元素的值,不能修改值。

       单向,可以使用++运算符进行递增操作,不能倒退。

2.输出迭代器:

  用于修改容器中元素的值,不能读取值。

  单向,可以使用++运算符进行递增操作,不能倒退。

多通迭代器:

3.前向迭代器:

       既可以读写数据,也可以只读数据。

  支持++p,p++,*p,=,==,!=。

  递增后,仍可以对前面的迭代器(已经保存的副本)值进行解引用操作。

        对应类型:forward_list,unordered_map,unordered_set

4.双向迭代器:

  包含所有正向迭代器的特性,并支持递减运算符(a--和--a)。

        对应类型:list、map、set

5.随机迭代器:

  包含了所有双向迭代器的特性,能够进行随机访问。

        支持,<,<=等比较运算符,p1<p2:p1经过至少一次++等于p2;支持p2-p1。

        对应类型:vector、queue

 以std::copy()函数为例:

//普通版本函数签名
template<class InputIterator, class OutputIterator>
OutputIterator copy(InputIterator first, InputIterator last, OutputIterator result);
//执行策略版本函数签名
template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2>
ForwardIterator copy(ExecutionPolicy&& policy, ForwardIterator1 first, ForwardIterator1 last, ForwardIterator2 result);

前向迭代器(返回真正引用)可以随意复制,副本可以等效使用,递增操作不会令副本失效,因而支持并行处理。若执行策略的重载支持输入迭代器(允许返回代理类型引用,能够转化为元素类型),则强迫每个线程共同使用唯一一个迭代器,从数据源序列读取值,这会令访问串行化。

3.1并行算法函数使用范例

最简单的范例是并行循环:对容器内的每个元素执行都某项操作,每个元素相互独立:

std::for_each(std::execution::par, v.begin(), v.end(), do);

一般情况下,我们会使用std::execution::par策略,在不需要同步的情况下,也可以选择std::execution::par_unseq策略,提高代码交错执行任务的可能性,也许不会产生更好的效果,因为策略本身只是一种许可。 

以下例子展示具有内部同步功能的类:

class X
{
	mutable std::mutex m;
	int data;
public:
	X():data(0){}
	int get_value()const
	{
		std::lock_guard guard(m);
		return data;
	}
	void increment()
	{
		std::lock_guard guard(m);
		++data;
	}
};
void increment_all(std::vector<X>& v)
{
	std::for_each(std::execution::par, v.begin(), v.end(),
		[](X& x) {x.increment(); });
}

因为每个X数据都有自己的互斥,无法使用std::execution::par_unseq策略,我们可以改为用互斥保护整个容器以适用该策略:

class X
{
	int data;
public:
	X():data(0){}
	int get_value()const
	{
		return data;
	}
	void increment()
	{
		++data;
	}
};
class ProtectedX
{
	std::mutex m;
	std::vector<X> v;
public:
	void lock()
	{
		m.lock();
	}
	void unlock()
	{
		m.unlock();
	}
	std::vector<X>& get_vec()
	{
		return v;
	}
};
void increment_all(ProtectedX& data)
{	
	std::lock_guard guard(data);//调用data.lock()
	auto& v = data.get_vec();
	std::for_each(std::execution::par, v.begin(), v.end(),
		[](X& x) {x.increment(); });
}

 缺点是锁粒度太大,若恰好有其它线程需要并发访问容器,则被迫等待。

3.2访问计数

假定我们需要处理某个网站的日志数据:每个页面的访问次数、访问的来源、用户所用浏览器等。处理分为两部分:逐行处理日志提炼相关信息,以及聚合信息结果。该场景适合使用并行算法函数,因为每行日志的处理完全独立,按行提炼出的结果逐步累计。

transform_reduce()正是为了这种类型的任务设计的,以统计访问每个页面的次数为例:

#include<vector>
#include<string>
#include<unordered_map>
#include<numeric>
struct log_info {
	std::string page;
	time_t visit_time;
	std::string browser;
};
//外部声明 假设别的代码写出了该函数,用于从一项目日志中提炼出相关信息
extern log_info parse_log_line(const std::string& line);
//页面网址与访问次数的映射
using visit_map_type = std::unordered_map<std::string, unsigned long long>;

visit_map_type count_visits_per_page(const std::vector<std::string>& log_lines)
{
	struct combine_visits {
		visit_map_type operator()(visit_map_type lhs, visit_map_type rhs)const
		{
			if (lhs.size() < rhs.size())
				std::swap(lhs, rhs);
			for (const auto& entry : rhs)
			{
				lhs[entry.first] += entry.second;
			}
			return lhs;
		}

		visit_map_type operator()(log_info log, visit_map_type map)const
		{
			++map[log.page];
			return map;
		}
		visit_map_type operator()(visit_map_type map, log_info log)const
		{
			++map[log.page];
			return map;
		}
		visit_map_type operator()(log_info log1, log_info log2)const
		{
			visit_map_type map;
			++map[log1.page];
			++map[log2.page];
			return map;
		}
	};
	//(执行策略、迭代器头尾、初始值、执行的函数、产生中间结果的函数)
	return std::transform_reduce(
		std::execution::par, log_lines.begin(), log_lines.end(),
		visit_map_type(), combine_visits(), parse_log_line
	);
}

std::transform_reduce对容器中的每个元素执行parse_log_line()函数,得到中间结果,类型为log_info结构体,然后对相邻的log_info执行combine_visits()聚合,因为相邻的数据可能具有不同类型,我们需要为不同类型数据的汇合设置重载函数(2个log,2个map,1个log1个map)。

设计并行计算本是困难的工作,但上述模式准许我们移交给标准库实现,我们只需关注如何求出结果。
 

C++ 并行计算 MPI Tutorial-4 目录点对点通讯应用-随机游走问题描述编码解决死锁和预防确认所有 Walker 完成参考 点对点通讯应用-随机游走 问题描述 问题的基本定义如下,给定一个 Min, Max, 和随机游走器 W,使得 W 在往右走 S 步。如果超出范围,则会重新回到起点。W 每次只能移动一个单位。 让我们概述一下如何并行处理随机游走。 与许多并行处理程序一样,第一项相关任务是在各个进程之间划分域。随机游走问题具有大小为 Max - Min + 1 的一维域。假设 Walker 只能走整数大小的步数,我们可以轻松地在整个过程 阅读详情

相关推荐

c++在一个cpp文件中调用另一个cpp文件的函数的两种方法

有时候写代码为了简便,会将一些函数方法单独在一个cpp的源文件中定义,然后在另一个源文件中需要用到自定义的函数时直接调用就可以了!学过c++的人可能最熟悉的方法还是利用头文件来进行调用,其实还有一种c语言当中的方法一般情况下同样可以适用与c++中! 方法1:创建头文件 举个简单的例子: 首先创建一个method.h头文件,声明一个求最大值的函数max(int x,int y),然后再创建一个同名的源文件method.cpp,在该文件中实现函数max(int x,int y)的功能。代码如下: //metho

weixin_43350361的博客 6万+

C++与并行计算:利用并行计算加速程序运行

并行计算是指将一个大型计算任务分解为多个小任务,并将这些小任务同时执行以提高计算速度的方法。通过将计算任务划分为多个子任务,每个子任务在不同的处理器核心或计算节点上并行执行,从而实现整体计算速度的提升。在传统的串行计算模式下,每个任务必须按照顺序执行,一个任务完成后才能进行下一个任务。而并行计算可以同时执行多个任务,充分利用计算资源,显著提升计算效率。

牛肉胡辣汤 4457

C++ 一个函数调用其他.cpp文件中的函数

使用VC或VS创建C++项目的时候,会自动产生许多文件夹,其中有一个文件夹->源文件: 在该文件下可以自定义许多.cpp文件,但是需要注意的是这里面的各个文件只能有一个文件中含有main()函数, 而且各个文件中不能使用相同的函数名进行定义; 那么要那么多文件放在项目中有什么用呢? 当然这里C++是提供一个文件调用其他文件中函数的功能的, 这就可以让我们自定义一个只包含main()...

⚡ 4万+

C++ 并行编程

TBB:Intel 公司开发的 TBB(Threading Building Blocks)是一个 C++ 并行编程库,提供了一组高级的并行算法和数据结构,可以简化并行编程的复杂度。多线程编程是一种常见的并行编程方法,可以使用 C++11 标准中的 std::thread 类或 POSIX 线程库来创建多个线程,实现并行计算。OpenCL:OpenCL 是一种跨平台的并行编程框架,可以使用 C++ 编写并行程序,支持多种硬件加速器,包括 CPU、GPU、FPGA 等。

qq_40553788的博客 2425

「C/C++」C++多线程 之 并发编程

C++通过其强大的标准库和灵活的语法特性,为并发编程提供了丰富的工具和手段。从基本的线程管理到高级的并行算法,再到异步编程的支持,C++都能满足不同的并发处理需求。然而,并发编程也带来了复杂性,开发者需要深入理解同步机制、线程安全等问题,以确保程序的正确性和性能。通过合理的设计和实践,C++并发编程可以极大地提升程序的执行效率和响应能力。何曾参静谧的博客。

何曾参静谧的博客 1059

使用C++进行数据并行化:并行算法简介

并行算法是C++17标准库中的一个新特性,它提供了一种简单而强大的方式来实现数据并行化。数据并行化是一种并行编程技术,它将数据分解为多个部分,然后在多个处理器上同时处理这些部分。C++17标准库中的大多数算法都有并行版本,包括但不限于std::for_each, std::transform, std::accumulate等。这些并行算法接受一个额外的参数,用于指定执行策略。

夏天的狂风的专栏 1027

【C++并行算法实战指南】:掌握高效并发编程的7个核心技巧

掌握C++并行算法实践的高效方法,解决多核并发编程难题。涵盖线程池、std::async、并行STL等核心技术,适用于高性能计算与大规模数据处理场景。提升程序执行效率,降低资源消耗,值得收藏。

IterStream的博客 1032

C++ 并发编程(C++11 到 C++17 )

为什么要并发编程大型的软件项目常常包含非常多的任务需要处理。例如:对于大量数据的数据流处理,或者是包含复杂GUI界面的应用程序。如果将所有的任务都以串行的方式执行,则整个系统的效率将会非常...

编程与实战的博客 4256

C++并发:并行算法函数

C++17向标准库加入了并行算法函数。他们是新引入的多个函数重载,比如std::find()、std::transform()和std::reduce(),其操作目标都是容器区间。相比各自对应的普通单线程版本,这些并行版本具有相同的函数签名,只是新增一个参数,用于设定执行策略。另外,并行执行方式会改变函数对复杂度的要求。因为并行算法需要处理的工作总量往往更多,才可以充分发挥系统算力。如果将一项任务分配到100个处理器上,但算法函数实现却另工作量变为原来的两倍,那么整体加速比只能达到50.

FranYeCisco的博客 1140

C++17并行算法与HIPSTDPAR

C++17标准在原有的C++标准库中引入了的概念。像这样的并行版本算法保持了与常规串行版本相同的签名,只是增加了一个额外的参数来指定使用的。这种灵活性使得已经使用算法的用户只需对代码进行最小程度的修改,就能利用多核架构的优势。从6.1开始,只要用户愿意添加一两个额外的编译器标志,这些并行算法就能通过无缝卸载到AMD加速器上执行。尽管提供的功能适用于所有AMD GPU(包括消费级显卡),但本篇博客主要聚焦于使用6.1的(分别对应和系列卡)。作为示例代码,我们将关注提供的求解器。

数字人生 1453

unity中基于NGUI实现一张图片上在某个地方挖个洞

按照策划的要求,引导时只有被引导的图片是高亮的,其余地方都是黑色半透明,如下图所示: 对应的实现shader如下: Shader "Unlit/TutorialBg" { Properties { _MainTex ("Base (RGB), Alpha (A)", 2D) = "black" {} _ClipRange0 ("Clip Vector

手机游戏开发 3698

【C++并发编程进阶】:为什么你的并行算法反而更慢?

掌握C++并行算法实践中的性能优化秘诀,解决多线程反而变慢的难题。涵盖适用场景、任务粒度控制与负载均衡策略,提升计算密集型程序效率,值得收藏。

ProceGlow的博客 1022

Tauri开发环境配置避坑指南:从Rust到Node.js的全流程实战

本文是一份详尽的Tauri开发环境配置实战指南,重点解析了从Rust工具链安装、Node.js版本管理到IDE配置的全流程。文章深入探讨了包管理器选择、依赖锁定、网络镜像加速等关键环节,并提供了开发与构建过程中典型问题的排查思路与解决方案,旨在帮助开发者高效避坑,顺利搭建跨平台桌面应用开发环境。

w3x4y的博客 292

【并发编程】第十章 并行算法

C++17 标准为 C++ 标准库引入了并行算法的概念。并行版本的函数签名与“普通”单线程版本相比,增加了一个新的参数std::execution::par 执行策略指示标准库可以使用多个线程。请注意,这是许可,而不是要求并行算法通常要做更多的总工作量,以便利用系统的并行性——如果可以将工作分配到100个处理器上,即使实现要做两倍的总工作,仍然可以获得50倍的整体加速。

Antonio915的博客 1396

机器视觉:9点标定的原理与实现

标定就是将机器视觉处理得到的像素坐标转换成实际项目中使用到的毫米坐标。简单说即使看看实际单位距离内有几个像素,如下图所示,10mm的距离内有222个像素,那像素坐标和实际的毫米坐标就有个比例关系了。

m0_49968063的博客 1万+

手把手教你用CsvView分析大疆无人机飞行日志(附实战CTF题解)

本文详细介绍了如何使用CsvView工具分析大疆无人机飞行日志,包括环境搭建、日志提取、核心功能解析及CTF实战技巧。通过实战案例,帮助读者掌握无人机取证的关键技术,提升日志分析能力,特别适合网络安全竞赛和实际取证场景。

weixin_42652674的博客 457

C++ 在一个cpp文件中使用另一个cpp文件中定义的函数

C++ 在一个cpp文件中 使用另一个cpp文件中定义的函数建立一个console项目头文件cpp文件main.cpp 建立一个console项目 以dev为例,在【文件】【新建】【项目】,新建一个console项目。 头文件 添加新文件,输入说要使用函数的声明,保存为.h文件。 int add(int a,int b); cpp文件 定义在.h中声明的函数,保存为.cpp文件。 #include<iostream> #include"chen.h"//不要忘记这个 int a

m0_43456002的博客 9264

在 SAP HANA XS Advanced 中用 InA 打通 Web 化分析数据访问:架构原理、部署步骤与实战指南

本文介绍了如何在SAP HANA环境中通过InA协议为XS Advanced应用和分析工具提供实时数据访问。主要内容包括:InA协议的作用是将HANA计算视图等模型通过HTTP(S)暴露为实时数据源;SAP HANA Analytics Adapter(xsahaa)是关键组件,负责协议转换和连接管理;部署包含本地和云端两种形式,均需建立XSA空间与租户数据库的映射;实施前需准备HDI容器、适配器构建和网络验证;安全方面通过XSA用户角色和HDI授权双重控制;文章还提供了与SAP Analytics Clo

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 259

并行算法_第十章_《C++并发编程实战》笔记

并行算法

C/C++ 1289

YOLO26涨点改进 | 全网独家复现、小目标检测改进篇 | TGRS 2025 | YOLO26引入MFAE-YOLO中的GFFP、FCPS 和 C3k2-FPEU创新点,涨点起飞,直接发论文

🔥本文给大家介绍在YOLO26中引入MFAE-YOLO中的 GFFP(全局特征融合处理)、FCPS(特征通道像素注意力) 和 C3k2-FPEU(特征池提取单元) 二次创新改进模块,能显著提升对小目标的检测性能。GFFP通过多尺度特征融合增强全局上下文感知能力,有效提升小目标在复杂背景下的可辨性;FCPS融合通道、像素和空间注意力机制,增强了模型对关键细节和小区域特征的关注,提升检测精度;C2F-FPEU利用多种池化方式挖掘细节特征,优化浅层特征表示能力。三者协同提升了YOLO26在小目标检测中的鲁棒性。

Ai缝合怪、助力小伙伴高效发论文 306

流体动力学仿真软件:SU2_(1).SU2简介与安装

SU2 是一个开源的计算流体动力学(CFD)和计算结构动力学(CSD)仿真软件,由斯坦福大学的航空航天系开发。它主要用于解决流体动力学问题,包括但不限于空气动力学、热力学、化学反应流等。SU2 的特点在于其高度的灵活性和可扩展性,使其成为科研和工业领域中非常受欢迎的工具。SU2 采用有限体积法(FVM)和有限元法(FEM)进行数值求解,支持多种物理模型和求解器,如 Euler 方程、Navier-Stokes 方程、RANS 方程等。

kkchenjj的博客 1313

闭关之 C++ 并发编程笔记(五):并行算法函数与测试

《C++ 并发编程实战 (第二版)》笔记

jiamada的博客 1756

ENVI_基于无人机数据的果树提取与相对健康监测

一、数据处理 1.计算植被指数VDVI或GDVI:Band Math / Spectral Indices 2.制作掩膜:ROI——Threshold——Subset 二、单地块果树提取 1.绘制感兴趣区shp 2.确定果树提取参数:Count Crops 3.输出果树矢量文件:Convert Crops To Shapefile 4.果树相对健康程度分析:Calculate Crop Me...

提供技术服务、资源分享 429690771 1400

【C++17 library features】深入解析 C++17 并行算法与执行策略

在现代计算需求飞速增长的背景下,**并行计算**成为了提升程序性能的关键手段。随着多核处理器的普及,单核性能的提升逐渐放缓,开发者需要利用并行算法充分挖掘硬件潜力。C++17 标准在此背景下引入了并行算法,为开发高效、可扩展的应用提供了强有力的工具。 “一种真正的发现之旅并非去寻找新大陆,而是拥有新的眼光。” ——马塞尔·普鲁斯特。正如普鲁斯特所言,引入并行算法让开发者以全新的视角审视并优化代码性能。

探索C++编程的奥秘,分享深入的技术见解和实践,旨在激发读者创造力与解决问题的思维。 1536

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

Multithreading-Cpp-Course:掌握现代C++并发编程的不二选择

Multithreading-Cpp-Course:掌握现代C++并发编程的不二选择 项目介绍 在现代软件开发领域,多线程编程是一个至关重要的技能。它不仅能提升程序的性能和响应速度,还能有效利用多核处理器的能力。Multithreading-Cpp-Course 是一套针对现代C++并发编程的教程源码,源自知名的在线教育平台Udemy上的课程 "Learn Multithreading ...

gitblog_01108的博客 705

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

【C++】C++ 并行算法(Parallel Algorithms)介绍

C++并行算法添加执行策略参数(如保证操作无数据竞争编译器自动处理线程管理fill:#333;color:#333;color:#333;fill:none;原始算法添加执行策略编译器生成并行代码自动线程池管理多核并行执行合理使用并行算法,可在现代多核CPU上轻松获得3-10倍的性能提升!

weixin_43510208的博客 1506

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

上一篇: C++并发编程(九)进阶线程管理
下一篇: C++并发编程(十一)多线程应用的测试和除错
Cvincent976
博客等级 码龄6年 34粉丝 20原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值