C++多线程编程(第四章 案例1,C++11和C++17 多核并行计算样例)
目录
- 4.1手动实现多核base16编码
- 4.1.1 实现base16编码
- 4.1.2无多线程代码
- 4.1.3 C++ 11多线程代码
- 4.1.4 C++ 17多线程并发
- 4.1.5 所有测试代码汇总
4.1手动实现多核base16编码
4.1.1 实现base16编码
二进制转换为字符串
一个字节8位,拆分为两个4位字节(最大值16)
拆分后的字节映射到0123456789abcdef
4.1.2无多线程代码
#include <thread>
#include<iostream>
#include<future>
#include <string>
#include <vector>
#include <chrono>//计时头,C++11using namespace std;
using namespace chrono;static const char base16[] = "0123456789abcdef";
void Base16Encode(const unsigned char* data, int size, unsigned char* out)
{for (int i = 0; i < size; i++){unsigned char d = data[i];//0000 0000//1234 5678 >> 4 => 0000 1234 移位操作//1234 5678 & 0000 1111 => 0000 5678char a = base16[d >> 4];//取出高位char b = base16[d & 0x0F];//取出低位out[i * 2] = a;out[i * 2+1] = b;}
}int main()
{//使用字符串进行16位编码测试string test_data = "测试base16编码";printf("test_data size=%d\n", test_data.size());//一个中文占用2个字节,一个英文占用1个字节,如果要解码出来包含中文和英文,有点难度unsigned char* out = new unsigned char[test_data.size()*2+1];Base16Encode((unsigned char*)test_data.data(), test_data.size(), out);//编码out[test_data.size()*2] = '\0';//字符串\0结尾,否则后面总有乱码cout << "base16:" << out << endl;//测试单线程base16编码效率{vector<unsigned char>in_data;in_data.resize(1024 * 1024 * 20);// 1024*1024*10 -> 10M 测试数据for (int i = 0; i < in_data.size(); i++){//初始化里面数据in_data[i] = i % 256;}vector<unsigned char>out_data;out_data.resize(in_data.size()*2);//是输入数据2倍auto start = system_clock::now();//计时开始Base16Encode(in_data.data(), in_data.size(),out_data.data());auto end = system_clock::now();//计时结束auto duration = duration_cast<milliseconds>(end-start);//模板函数,转换到毫秒cout << "编码:" << in_data.size() << "字节数据花费" << duration.count() << "毫秒" << endl;//cout << out_data.data() << endl;}printf("All done!\n");getchar();return 0;
}

4.1.3 C++ 11多线程代码
//C++11多线程
void Base16EncodeThread(const vector<unsigned char>&data, vector<unsigned char> &out)
{long size = data.size();int th_count = thread::hardware_concurrency();//系统支持的线程核心数printf("CPU report thread count:%d\n",th_count);//对原始数据进行切片long slice_count = size / th_count;//余数丢弃了,余数后续单独处理if (size < th_count){//只切一片th_count = 1;//1个线程搞定slice_count = size;}vector<thread> ths;//准备好线程ths.resize(th_count);//任务分配到各个线程 for (int i = 0; i < th_count; i++){//eg. 1234 5678 9abc defg hi//计算偏移位置long offset = i * slice_count;long count = slice_count;//最后一个线程要把余数加起来一起处理if (th_count > 1 && i == th_count - 1){count = slice_count + size%th_count;}//cout << offset << ":" << count << endl;ths[i] = thread(Base16Encode, data.data() + offset,count, out.data());}//等待所有线程处理结束for (auto &th : ths){th.join();}
}
4.1.4 C++ 17多线程并发
printf("C++17多线程Base16编码效率测试(编译的时候先检查设置C++17) 开始计算===========================\n");//设置C++17方法:属性->C/C++ ->C++语言标准 ,设置ISOC++17vector<unsigned char>in_data;in_data.resize(TestNumber);// 1024*1024*10 -> 10M 测试数据for (int i = 0; i < in_data.size(); i++){//初始化里面数据in_data[i] = i % 256;}vector<unsigned char>out_data;out_data.resize(in_data.size() * 2);//是输入数据2倍auto start = system_clock::now();//计时开始//#include <execution> //C++17 支持std::for_each(std::execution::par,//并行计算 多核in_data.begin(),in_data.end(),[&](auto& d)//多线程进入此函数{char a = base16[(d >> 4)];char b = base16[(d & 0x0F)];int index = &d - in_data.data();out_data[index * 2] = a;out_data[index * 2 + 1] = b;});auto end = system_clock::now();//计时结束auto duration = duration_cast<milliseconds>(end - start);//模板函数,转换到毫秒cout << "C++17多线程 编码:" << in_data.size() << "字节数据花费" << duration.count() << "毫秒" << endl;
4.1.5 所有测试代码汇总
#include <thread>
#include<iostream>
#include<future>
#include <string>
#include <vector>
#include <chrono>//计时头,C++11#include <execution> //C++17 for_eachusing namespace std;
using namespace chrono;static const char base16[] = "0123456789abcdef";
void Base16Encode(const unsigned char* data, long size, unsigned char* out)
{for (int i = 0; i < size; i++){unsigned char d = data[i];//0000 0000//1234 5678 >> 4 => 0000 1234 移位操作//1234 5678 & 0000 1111 => 0000 5678char a = base16[d >> 4];//取出高位char b = base16[d & 0x0F];//取出低位out[i * 2] = a;out[i * 2+1] = b;}
}//C++11多线程
void Base16EncodeThread(const vector<unsigned char>&data, vector<unsigned char> &out)
{long size = data.size();int th_count = thread::hardware_concurrency();//系统支持的线程核心数printf("CPU report thread count:%d\n",th_count);//对原始数据进行切片long slice_count = size / th_count;//余数丢弃了,余数后续单独处理if (size < th_count){//只切一片th_count = 1;//1个线程搞定slice_count = size;}vector<thread> ths;//准备好线程ths.resize(th_count);//任务分配到各个线程 for (int i = 0; i < th_count; i++){//eg. 1234 5678 9abc defg hi//计算偏移位置long offset = i * slice_count;long count = slice_count;//最后一个线程要把余数加起来一起处理if (th_count > 1 && i == th_count - 1){count = slice_count + size%th_count;}//cout << offset << ":" << count << endl;ths[i] = thread(Base16Encode, data.data() + offset,count, out.data());}//等待所有线程处理结束for (auto &th : ths){th.join();}
}int main()
{int TestNumber = 1024 * 1024 * 20 - 1; //1024 * 1024 * 10 -> 10M 测试数据大小//使用字符串进行16位编码测试string test_data = "测试base16编码";printf("test_data size=%d\n", test_data.size());//一个中文占用2个字节,一个英文占用1个字节,如果要解码出来包含中文和英文,有点难度unsigned char* out = new unsigned char[test_data.size()*2+1];Base16Encode((unsigned char*)test_data.data(), test_data.size(), out);//编码out[test_data.size()*2] = '\0';cout << "base16:" << out << endl;//测试单线程base16编码效率{printf("单线程Base16编码效率测试 开始计算===========================\n");vector<unsigned char>in_data;in_data.resize(TestNumber);// 1024*1024*10 -> 10M 测试数据for (int i = 0; i < in_data.size(); i++){//初始化里面数据in_data[i] = i % 256;}vector<unsigned char>out_data;out_data.resize(in_data.size()*2);//是输入数据2倍auto start = system_clock::now();//计时开始Base16Encode(in_data.data(), in_data.size(),out_data.data());auto end = system_clock::now();//计时结束auto duration = duration_cast<milliseconds>(end-start);//模板函数,转换到毫秒cout << "编码:" << in_data.size() << "字节数据花费" << duration.count() << "毫秒" << endl;//cout << out_data.data() << endl;//预览编码后的文本}//测试C++11多线程base16编码效率{printf("C++11多线程Base16编码效率测试 开始计算===========================\n");vector<unsigned char>in_data;in_data.resize(TestNumber);// 1024*1024*10 -> 10M 测试数据for (int i = 0; i < in_data.size(); i++){//初始化里面数据in_data[i] = i % 256;}vector<unsigned char>out_data;out_data.resize(in_data.size() * 2);//是输入数据2倍auto start = system_clock::now();//计时开始Base16EncodeThread(in_data, out_data);//多线程auto end = system_clock::now();//计时结束auto duration = duration_cast<milliseconds>(end - start);//模板函数,转换到毫秒cout << "C++11多线程 编码:" << in_data.size() << "字节数据花费" << duration.count() << "毫秒" << endl;//cout << out_data.data() << endl;//预览编码后的文本}//测试C++11多线程base16编码效率{printf("C++17多线程Base16编码效率测试(编译的时候先检查设置C++17) 开始计算===========================\n");//设置C++17方法:属性->C/C++ ->C++语言标准 ,设置ISOC++17vector<unsigned char>in_data;in_data.resize(TestNumber);// 1024*1024*10 -> 10M 测试数据for (int i = 0; i < in_data.size(); i++){//初始化里面数据in_data[i] = i % 256;}vector<unsigned char>out_data;out_data.resize(in_data.size() * 2);//是输入数据2倍auto start = system_clock::now();//计时开始//#include <execution> //C++17 支持std::for_each(std::execution::par,//并行计算 多核in_data.begin(),in_data.end(),[&](auto& d)//多线程进入此函数{char a = base16[(d >> 4)];char b = base16[(d & 0x0F)];int index = &d - in_data.data();out_data[index * 2] = a;out_data[index * 2 + 1] = b;});auto end = system_clock::now();//计时结束auto duration = duration_cast<milliseconds>(end - start);//模板函数,转换到毫秒cout << "C++17多线程 编码:" << in_data.size() << "字节数据花费" << duration.count() << "毫秒" << endl;//cout << out_data.data() << endl;//预览编码后的文本}printf("All done!\n");getchar();return 0;
}

分析:
release版本优化的比较多,之所以C++17耗时较长原因是进入多线程次数远远大于C++11,C++11只进入了12次,而C++17采用lambda表达式函数,进入了TestNumber次
相关文章:
C++多线程编程(第四章 案例1,C++11和C++17 多核并行计算样例)
目录 4.1手动实现多核base16编码4.1.1 实现base16编码4.1.2无多线程代码4.1.3 C 11多线程代码4.1.4 C 17多线程并发4.1.5 所有测试代码汇总 4.1手动实现多核base16编码 4.1.1 实现base16编码 二进制转换为字符串 一个字节8位,拆分为两个4位字节(最大值…...
获取远程仓库的信息和远程分支的信息
前记: git svn sourcetree gitee github gitlab gitblit gitbucket gitolite gogs 版本控制 | 仓库管理 ---- 系列工程笔记. Platform:Windows 10 Git version:git version 2.32.0.windows.1 Function:获取远程仓库的信息和远…...
QT学习day1
一、思维导图 二、作业:实现登录界面 #include "widget.h" #include<QDebug> #include<QIcon>Widget::Widget(QWidget *parent): QWidget(parent) {/**********************窗口******************///设置窗口图标this->setWindowTitle…...
unity面试八股文 - 框架设计与资源管理
Unity项目框架是如何设计的?有哪些原则 在设计Unity项目框架时,通常会遵循一些基本的原则和步骤。以下是主要的一些原则: 模块化:每个功能都应该被作为一个独立的模块来处理,这样可以方便修改和维护。 低耦合&#x…...
智能网关IOT 2050采集应用
SIMATIC IOT2050 是西门子公司新推出的应用于企业数字化转型的智能边缘计算和云连接网关。 它将云、公司内 IT 和生产连接在一起,专为直接在生产环境中获取、处理和传输数据的工业 IT 解 决方案而设计。例如,它可用于将生产 过程与基于云的机器和生产数据…...
iOS代码混淆-从入门到放弃
目录 1. 什么是iOS代码混淆? 2. iOS自动代码混淆的方法是什么? 3. iOS代码混淆的作用是什么? 4. 怎么样才能做到更好的iOS代码混淆? 总结 参考资料 1. 什么是iOS代码混淆? 代码混淆是指将程序中的方法名、属…...
基于Eigen的位姿转换
位姿中姿态的表示形式有很多种,比如:旋转矩阵、四元数、欧拉角、旋转向量等等。这里基于Eigen实现四种数学形式的相互转换功能。本文利用Eigen实现上述四种形式的相互转换。我这里给出一个SE3(4*4)(先平移、再旋转)的构建方法&…...
Jmeter之Bean shell使用详解
一、什么是Bean Shell BeanShell是一种完全符合Java语法规范的脚本语言,并且又拥有自己的一些语法和方法;BeanShell是一种松散类型的脚本语言(这点和JS类似); BeanShell是用Java写成的,一个小型的、免费的、可以下载的、嵌入式的Java源代码解释器,具有对象脚本语言特性,非常精…...
TCP/IP(八)TCP的连接管理(五)四次握手
一 tcp连接断开 每一个TCP报文的超时重传都由一个特定的内核参数来控制 ① 四次握手的过程 遗留: 谁先发送FIN包,一定是client吗? --> upload和download补充: 主动和被动断开连接的场景 "四次握手过程描述" F --> FIN --> F…...
MyBatis-Plus主键生成策略[MyBatis-Plus系列] - 第491篇
历史文章(文章累计490) 《国内最全的Spring Boot系列之一》 《国内最全的Spring Boot系列之二》 《国内最全的Spring Boot系列之三》 《国内最全的Spring Boot系列之四》 《国内最全的Spring Boot系列之五》 《国内最全的Spring Boot系列之六》 …...
Spring——和IoC相关的特性
目录 IoC中Bean的生命周期 实例化(Instantiation) 属性注入(Populate Properties) 初始化(Initialization) 使用(Bean in Use) 销毁(Destruction) Laz…...
在 TensorFlow 中调试
如果调试是消除软件错误的过程,那么编程一定是添加错误的过程。Edsger Dijkstra。来自 https://www.azquotes.com/quote/561997 一、说明 在这篇文章中,我想谈谈 TensorFlow 中的调试。 在之前的一些帖子(此处、此处和此处)中&…...
想要精通算法和SQL的成长之路 - 连续的子数组和
想要精通算法和SQL的成长之路 - 连续的子数组和 前言一. 连续的子数组和1.1 最原始的前缀和1.2 前缀和 哈希表 前言 想要精通算法和SQL的成长之路 - 系列导航 一. 连续的子数组和 原题链接 1.1 最原始的前缀和 如果这道题目,用前缀和来算,我们的思路…...
【C++】头文件chrono
2023年10月16日,周一晚上 当前我只是简单的了解了一下chrono 以后可能会深入了解chrono并更新文章 目录 功能原理头文件chrono中的一些类头文件chrono中的数据类型一个简单的示例程序小实验:证明a的效率比a高 功能 这个chrono头文件是用来处理时间的…...
Python学习六
前言:相信看到这篇文章的小伙伴都或多或少有一些编程基础,懂得一些linux的基本命令了吧,本篇文章将带领大家服务器如何部署一个使用django框架开发的一个网站进行云服务器端的部署。 文章使用到的的工具 Python:一种编程语言&…...
Springboot 集成 WebSocket
WebSocket是一种在单个TCP连接上进行全双工通信的协议。WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接…...
谨以此篇,纪念我2023年曲折的计算机保研之路
目录 阶段一:迷茫阶段二:准备个人意愿保研材料准备套磁老师5.1日 浙大线上编程测试5.8日 浙大线上面试 —— 一面5.17日 浙大线上面试——二面5.29日 实验室面试结果5.27日 南开线上面试6.20日 华师电话面试 阶段三:旅途北航CS(6.…...
VSS、VDD、VBAT、VSSA
引言 在学习设计TM32时,发现芯片除了GPIO引脚外还会引出许多引脚,以STM32F407ZGT6为例除了GPIO引脚还会有以下引脚 如VSS、VDD、VBAT、VSSA、NRST、VREF、VDDA、VCAP_1、VCAP_2、PDR_ON这些引脚。他们有何作用,电路设计中应如何连接&#x…...
【Rust基础③】方法method、泛型与特征
文章目录 6 方法 Method6.1 定义方法self、&self 和 &mut self 6.2 自动引用和解引用6.3 关联函数 7 泛型和特征7.1 泛型 Generics7.1.1 结构体中使用泛型7.1.2 枚举中使用泛型7.1.3 方法中使用泛型为具体的泛型类型实现方法 7.1.4 const 泛型 7.2 特征 Trait7.2.1 为类…...
48.排列问题求解
思路分析:通过为每一队分配一个id,join条件要求t1.num < t2.num实现相同两队只比一次 代码实现: with t as (SELECT team_name,caseteam_nameWHEN 勇士 then 1WHEN 湖人 then 2WHEN 灰熊 then 3else 4end numFROM team )SELECT t1.team_…...
SkyWalking 10.2.0 SWCK 配置过程
SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外,K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案,全安装在K8S群集中。 具体可参…...
UE5 学习系列(三)创建和移动物体
这篇博客是该系列的第三篇,是在之前两篇博客的基础上展开,主要介绍如何在操作界面中创建和拖动物体,这篇博客跟随的视频链接如下: B 站视频:s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...
对WWDC 2025 Keynote 内容的预测
借助我们以往对苹果公司发展路径的深入研究经验,以及大语言模型的分析能力,我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际,我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测,聊作存档。等到明…...
【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】
1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件(System Property Definition File),用于声明和管理 Bluetooth 模块相…...
Python如何给视频添加音频和字幕
在Python中,给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加,包括必要的代码示例和详细解释。 环境准备 在开始之前,需要安装以下Python库:…...
大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计
随着大语言模型(LLM)参数规模的增长,推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长,而KV缓存的内存消耗可能高达数十GB(例如Llama2-7B处理100K token时需50GB内存&a…...
基于TurtleBot3在Gazebo地图实现机器人远程控制
1. TurtleBot3环境配置 # 下载TurtleBot3核心包 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone -b noetic-devel https://github.com/ROBOTIS-GIT/turtlebot3.git git clone -b noetic https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git git clone -b noetic-dev…...
iOS性能调优实战:借助克魔(KeyMob)与常用工具深度洞察App瓶颈
在日常iOS开发过程中,性能问题往往是最令人头疼的一类Bug。尤其是在App上线前的压测阶段或是处理用户反馈的高发期,开发者往往需要面对卡顿、崩溃、能耗异常、日志混乱等一系列问题。这些问题表面上看似偶发,但背后往往隐藏着系统资源调度不当…...
Python Einops库:深度学习中的张量操作革命
Einops(爱因斯坦操作库)就像给张量操作戴上了一副"语义眼镜"——让你用人类能理解的方式告诉计算机如何操作多维数组。这个基于爱因斯坦求和约定的库,用类似自然语言的表达式替代了晦涩的API调用,彻底改变了深度学习工程…...
在 Spring Boot 项目里,MYSQL中json类型字段使用
前言: 因为程序特殊需求导致,需要mysql数据库存储json类型数据,因此记录一下使用流程 1.java实体中新增字段 private List<User> users 2.增加mybatis-plus注解 TableField(typeHandler FastjsonTypeHandler.class) private Lis…...
