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_…...
18.(开发工具篇Gitlab)Git如何回退到指定版本
首先: 使用git log命令查看提交历史,找到想要回退的版本的commit id. 使用git reset命令 第一步:git reset --hard 命令是强制回到某一个版本。执行后本地工程回退到该版本。 第二步:利用git push -f命令强制推到远程 如下所示: 优点:干净利落,回滚后完全回到最初状态…...
IDEA初始配置
1. 详细设置 安装完IDEA之后的简单配置。 1.1 如何打开详细配置界面 1、显示工具栏 2、选择详细配置菜单或按钮 1.2 系统设置 1、默认启动项目配置 启动IDEA时,默认自动打开上次开发的项目?还是自己选择? 如果去掉Reopen projects on …...
WM_COPYDATA传回返回值的一个方案
方案背景 适应场景,通过WM_COPYDATA进行进程间通信时,SendMessage不能返回自定义的数据,由此想到以下思路解决这个问题 A进程使用VirtualAlloc分配一块内存,通过某种方式将此地址以及A进程ID传给另一个进程B B进程使用OpenProce…...
【日常业务开发】接口性能优化
【日常业务开发】接口性能优化 缓存本地缓存分布式缓存 数据库分库分表SQL 优化 业务程序并行化异步化池化技术预先计算事务粒度批量读写锁的粒度尽快return上下文传递空间换时间集合空间大小 缓存 本地缓存 本地缓存,最大的优点是应用和cache同一个进程内部&…...
Android 10.0 禁止弹出系统simlock的锁卡弹窗功能实现
1.前言 在10.0的系统开发中,在一款产品中,需要实现simlock锁卡功能,在系统实现锁卡功能以后,在开机的过程中,或者是在插入sim卡 后,当系统检测到是禁用的sim卡后,就会弹出simlock锁卡弹窗,要求输入puk 解锁密码,功能需求禁用这个弹窗,所以就需要看是 哪里弹的,禁用…...
VulnHub lazysysadmin
一、信息收集 1.nmap扫描开发端口 开放了:22、80、445 访问80端口,没有发现什么有价值的信息 2.扫描共享文件 enum4linux--扫描共享文件 使用: enum4linux 192.168.103.182windows访问共享文件 \\192.168.103.182\文件夹名称信息收集&…...
ppt怎么压缩到10m以内?分享ppt缩小方法
在日常工作中,我们常常需要制作和分享PowerPoint演示文稿,然而,有时候文稿中的图片、视频等元素会导致文件过大,无法在电子邮件或其他平台上顺利传输。为了将PPT文件压缩到10M以内,我们可以使用一些专门的文件压缩工具…...
智能警用装备管理系统-科技赋能警务
警用物资装备管理系统(智装备DW-S304)是依托互云计算、大数据、RFID技术、数据库技术、AI、视频分析技术对警用装备进行统一管理、分析的信息化、智能化、规范化的系统。 (1)感知智能化 装备感知是整个方案的基础,本方…...
攻防千层饼
近年来,网络安全领域正在经历一场不断升级的攻防对抗,这场攻防已经不再局限于传统的攻击与防御模式,攻击者和防守者都已经越发熟练,对于传统攻防手法了如指掌。 在这个背景下,攻击者必须不断寻求创新的途径࿰…...
组件封装使用?
组件封装是指在软件开发中,将功能代码或数据封装成一个独立的、可重用的模块或组件。这种封装可以使得代码更加模块化、可维护性和可重用性。在许多编程语言和开发框架中,都有不同的方式来实现组件封装。 以下是一些常见的组件封装方法和技巧࿱…...
苏宁易购网站建设 的定位/网络营销论坛
http://acm.hdu.edu.cn/showproblem.php?pid1142 Dijkstra求最短路径,记录最短路径的条数,cnt记录最短路径的条数出错,不知道错在哪里? View Code 1 #include<iostream> 2 #include<cstring> 3 #include<clim…...
.net网站 作品/网站seo视频狼雨seo教程
1. interrupt()说明 在介绍终止线程的方式之前,有必要先对interrupt()进行了解。 关于interrupt(),java的djk文档描述如下:http://docs.oracle.com/javase/7/docs/api/ Interrupts this thread. Unless the current thread is interrupting…...
优质做网站价格/线上培训
Java基础语法 今日内容介绍 u 方法 第1章 方法 1.1 方法概述 在我们的日常生活中,方法可以理解为要做某件事情,而采取的解决办法。 如:小明同学在路边准备坐车来学校学习。这就面临着一件事情(坐车到学校这件事情)需要…...
建湖网站设计/百度网盘云资源搜索引擎
当我们需要在缓存被移除的时候,得到通知产生回调,并做一些额外处理工作。这个时候RemovalListener就派上用场了。 public class Main {// 创建一个监听器private static class MyRemovalListener implements RemovalListener<Integer, Integer> {O…...
建设网站的工作职责/刷移动关键词优化
过劳死的精英每年都会有几个,其中最多的就是办公室白领,IT精英也占很大的比重。 13号有个新闻,“奥美公关北京公司一名24岁男性员工在办公室突发心脏病,经抢救无效死亡。早在2008年,奥美公司一位广告总监也因心脏病突发…...
洛阳哪有做公司网站的/网站推广优化方案
主窗口(key window)接受特定事件 一个窗口当前能接受键盘和非触摸事件时,便被认为是主窗口。而触摸事件则被投递到触摸发生的窗口,没有相应坐标值的事件被投递到主窗口。同一时刻只有一个窗口是主窗口。 大部分时间内,应用窗口是主窗口…...