当前位置: 首页 > news >正文

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位&#xff0c;拆分为两个4位字节&#xff08;最大值…...

获取远程仓库的信息和远程分支的信息

前记&#xff1a; git svn sourcetree gitee github gitlab gitblit gitbucket gitolite gogs 版本控制 | 仓库管理 ---- 系列工程笔记. Platform&#xff1a;Windows 10 Git version&#xff1a;git version 2.32.0.windows.1 Function&#xff1a;获取远程仓库的信息和远…...

QT学习day1

一、思维导图 二、作业&#xff1a;实现登录界面 #include "widget.h" #include<QDebug> #include<QIcon>Widget::Widget(QWidget *parent): QWidget(parent) {/**********************窗口******************///设置窗口图标this->setWindowTitle…...

unity面试八股文 - 框架设计与资源管理

Unity项目框架是如何设计的&#xff1f;有哪些原则 在设计Unity项目框架时&#xff0c;通常会遵循一些基本的原则和步骤。以下是主要的一些原则&#xff1a; 模块化&#xff1a;每个功能都应该被作为一个独立的模块来处理&#xff0c;这样可以方便修改和维护。 低耦合&#x…...

智能网关IOT 2050采集应用

SIMATIC IOT2050 是西门子公司新推出的应用于企业数字化转型的智能边缘计算和云连接网关。 它将云、公司内 IT 和生产连接在一起&#xff0c;专为直接在生产环境中获取、处理和传输数据的工业 IT 解 决方案而设计。例如&#xff0c;它可用于将生产 过程与基于云的机器和生产数据…...

iOS代码混淆-从入门到放弃

​ 目录 1. 什么是iOS代码混淆&#xff1f; 2. iOS自动代码混淆的方法是什么&#xff1f; 3. iOS代码混淆的作用是什么&#xff1f; 4. 怎么样才能做到更好的iOS代码混淆&#xff1f; 总结 参考资料 1. 什么是iOS代码混淆&#xff1f; 代码混淆是指将程序中的方法名、属…...

基于Eigen的位姿转换

位姿中姿态的表示形式有很多种&#xff0c;比如&#xff1a;旋转矩阵、四元数、欧拉角、旋转向量等等。这里基于Eigen实现四种数学形式的相互转换功能。本文利用Eigen实现上述四种形式的相互转换。我这里给出一个SE3&#xff08;4*4&#xff09;(先平移、再旋转)的构建方法&…...

Jmeter之Bean shell使用详解

一、什么是Bean Shell BeanShell是一种完全符合Java语法规范的脚本语言,并且又拥有自己的一些语法和方法;BeanShell是一种松散类型的脚本语言(这点和JS类似); BeanShell是用Java写成的,一个小型的、免费的、可以下载的、嵌入式的Java源代码解释器,具有对象脚本语言特性,非常精…...

TCP/IP(八)TCP的连接管理(五)四次握手

一 tcp连接断开 每一个TCP报文的超时重传都由一个特定的内核参数来控制 ① 四次握手的过程 遗留&#xff1a; 谁先发送FIN包,一定是client吗? --> upload和download补充&#xff1a; 主动和被动断开连接的场景 "四次握手过程描述" F --> FIN --> F…...

MyBatis-Plus主键生成策略[MyBatis-Plus系列] - 第491篇

历史文章&#xff08;文章累计490&#xff09; 《国内最全的Spring Boot系列之一》 《国内最全的Spring Boot系列之二》 《国内最全的Spring Boot系列之三》 《国内最全的Spring Boot系列之四》 《国内最全的Spring Boot系列之五》 《国内最全的Spring Boot系列之六》 ​…...

Spring——和IoC相关的特性

目录 IoC中Bean的生命周期 实例化&#xff08;Instantiation&#xff09; 属性注入&#xff08;Populate Properties&#xff09; 初始化&#xff08;Initialization&#xff09; 使用&#xff08;Bean in Use&#xff09; 销毁&#xff08;Destruction&#xff09; Laz…...

在 TensorFlow 中调试

如果调试是消除软件错误的过程&#xff0c;那么编程一定是添加错误的过程。Edsger Dijkstra。来自 https://www.azquotes.com/quote/561997 一、说明 在这篇文章中&#xff0c;我想谈谈 TensorFlow 中的调试。 在之前的一些帖子&#xff08;此处、此处和此处&#xff09;中&…...

想要精通算法和SQL的成长之路 - 连续的子数组和

想要精通算法和SQL的成长之路 - 连续的子数组和 前言一. 连续的子数组和1.1 最原始的前缀和1.2 前缀和 哈希表 前言 想要精通算法和SQL的成长之路 - 系列导航 一. 连续的子数组和 原题链接 1.1 最原始的前缀和 如果这道题目&#xff0c;用前缀和来算&#xff0c;我们的思路…...

【C++】头文件chrono

2023年10月16日&#xff0c;周一晚上 当前我只是简单的了解了一下chrono 以后可能会深入了解chrono并更新文章 目录 功能原理头文件chrono中的一些类头文件chrono中的数据类型一个简单的示例程序小实验&#xff1a;证明a的效率比a高 功能 这个chrono头文件是用来处理时间的…...

Python学习六

前言&#xff1a;相信看到这篇文章的小伙伴都或多或少有一些编程基础&#xff0c;懂得一些linux的基本命令了吧&#xff0c;本篇文章将带领大家服务器如何部署一个使用django框架开发的一个网站进行云服务器端的部署。 文章使用到的的工具 Python&#xff1a;一种编程语言&…...

Springboot 集成 WebSocket

WebSocket是一种在单个TCP连接上进行全双工通信的协议。WebSocket使得客户端和服务器之间的数据交换变得更加简单&#xff0c;允许服务端主动向客户端推送数据。在WebSocket API中&#xff0c;浏览器和服务器只需要完成一次握手&#xff0c;两者之间就直接可以创建持久性的连接…...

谨以此篇,纪念我2023年曲折的计算机保研之路

目录 阶段一&#xff1a;迷茫阶段二&#xff1a;准备个人意愿保研材料准备套磁老师5.1日 浙大线上编程测试5.8日 浙大线上面试 —— 一面5.17日 浙大线上面试——二面5.29日 实验室面试结果5.27日 南开线上面试6.20日 华师电话面试 阶段三&#xff1a;旅途北航CS&#xff08;6.…...

VSS、VDD、VBAT、VSSA

引言 在学习设计TM32时&#xff0c;发现芯片除了GPIO引脚外还会引出许多引脚&#xff0c;以STM32F407ZGT6为例除了GPIO引脚还会有以下引脚 如VSS、VDD、VBAT、VSSA、NRST、VREF、VDDA、VCAP_1、VCAP_2、PDR_ON这些引脚。他们有何作用&#xff0c;电路设计中应如何连接&#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.排列问题求解

思路分析&#xff1a;通过为每一队分配一个id&#xff0c;join条件要求t1.num < t2.num实现相同两队只比一次 代码实现&#xff1a; with t as (SELECT team_name,caseteam_nameWHEN 勇士 then 1WHEN 湖人 then 2WHEN 灰熊 then 3else 4end numFROM team )SELECT t1.team_…...

CosyVoice-300M Lite实战案例:在线教育语音课件生成系统

CosyVoice-300M Lite实战案例&#xff1a;在线教育语音课件生成系统 1. 为什么在线教育需要专属语音合成系统&#xff1f; 你有没有遇到过这样的场景&#xff1a;一位初中物理老师想为“浮力原理”这节课制作配套音频讲解&#xff0c;但反复试了三款主流TTS工具——要么普通话…...

ESP8266 AT指令实战:用NodeMCU连接WiFi并发送HTTP请求(2023最新版)

ESP8266 AT指令实战&#xff1a;用NodeMCU连接WiFi并发送HTTP请求&#xff08;2023最新版&#xff09; 当你拿起一块NodeMCU开发板时&#xff0c;它可能看起来只是块普通的电路板&#xff0c;但内置的ESP8266芯片让它成为了物联网开发的瑞士军刀。不同于Arduino需要额外WiFi模块…...

旧设备优化指南:iPhone 6s系统降级与性能提升全攻略

旧设备优化指南&#xff1a;iPhone 6s系统降级与性能提升全攻略 【免费下载链接】Legacy-iOS-Kit An all-in-one tool to downgrade/restore, save SHSH blobs, and jailbreak legacy iOS devices 项目地址: https://gitcode.com/gh_mirrors/le/Legacy-iOS-Kit 当你的iP…...

AI赋能无障碍:CYBER-VISION在智能导盲场景中的落地实践

AI赋能无障碍&#xff1a;CYBER-VISION在智能导盲场景中的落地实践 1. 引言&#xff1a;当科技照亮黑暗 想象一下&#xff0c;当你闭上眼睛走在繁忙的街道上&#xff0c;周围是川流不息的人群和车辆。对于全球2.85亿视障人士来说&#xff0c;这不仅是想象&#xff0c;而是每天…...

APKMirror客户端:安卓应用安全下载与管理的革新方案

APKMirror客户端&#xff1a;安卓应用安全下载与管理的革新方案 【免费下载链接】APKMirror 项目地址: https://gitcode.com/gh_mirrors/ap/APKMirror 在安卓应用获取的过程中&#xff0c;用户常常面临两难选择&#xff1a;官方应用商店的更新滞后与第三方平台的安全隐…...

避坑指南:rviz多点导航插件编译失败?可能是你的ROS版本或消息类型不匹配

避坑指南&#xff1a;rviz多点导航插件编译失败&#xff1f;可能是你的ROS版本或消息类型不匹配 当你满怀期待地从GitHub克隆了一个功能强大的rviz多点导航插件&#xff0c;准备为自己的机器人系统增添顺序导航能力时&#xff0c;却遭遇了令人沮丧的编译错误——这种经历对于RO…...

ESP8266配网总失败?详解AirLink和SoftAP两种模式在机智云项目中的实战区别与选择

ESP8266配网失败全解析&#xff1a;从AirLink到SoftAP的深度诊断手册 配网失败时&#xff0c;ESP8266的红色LED灯常亮像在嘲笑你的无能——这可能是物联网开发者最熟悉的挫败感。当机智云项目卡在最后10%的配网环节&#xff0c;那种"硬件没问题、代码没报错&#xff0c;但…...

找不到api-ms-win-core-path-l1-1-0.dll的官方解决方法(2026更新)

我是一名企业的IT桌面支持&#xff0c;平时处理得最多的就是员工电脑上五花八门的软件报错。最近&#xff0c;api-ms-win-core-path-l1-1-0.dll缺失的工单量激增&#xff0c;尤其在Windows 7系统的电脑上。很多同事第一反应是去网上搜这个文件下载&#xff0c;但这恰恰是IT运维…...

Qwen3-ASR-0.6B开发者案例:为小程序集成实时语音转写能力的技术路径

Qwen3-ASR-0.6B开发者案例&#xff1a;为小程序集成实时语音转写能力的技术路径 1. 项目背景与需求 最近接到一个很有意思的需求&#xff1a;一家在线教育公司想要在他们的微信小程序里加入实时语音转写功能。想象一下这个场景——老师在手机上讲课&#xff0c;学生的手机屏幕…...

Qwen3-VL量化版实测:8bit精度仅降0.13%的奥秘

Qwen3-VL量化版实测&#xff1a;8bit精度仅降0.13%的奥秘 【免费下载链接】Qwen3-VL-8B-Instruct-w8a8s-310 项目地址: https://ai.gitcode.com/Eco-Tech/Qwen3-VL-8B-Instruct-w8a8s-310 导语&#xff1a;阿里云Qwen3-VL视觉语言模型推出8bit量化版本Qwen3-VL-8B-Inst…...