C++多线程编程(第四章 案例1,C++11和C++17 多核并行计算样例)

news2024/11/20 13:35:30

目录

    • 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++11


using 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 5678
		char 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++17
		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();//计时开始
		//#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_each


using 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 5678
		char 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++17
		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();//计时开始
		//#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次

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1098761.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

产品经理必备的14款需求管理工具推荐!

产品管理需求在产品经理的日常工作中扮演着至关重要的角色&#xff0c;这一关键任务为产品开发工作和资源投入提供了坚实的基础&#xff0c;它是创造杰出产品的必不可少前提。 面对各式各样的需求&#xff0c;产品经理可以使用专业的需求管理工具来进行集中收集和管理&#xf…

VulnHub Alice

一、信息收集 发现开发了22、80 2.访问ip&#xff0c;右击查看源代码 发现需要利用X-Forwarded-For 火狐插件&#xff1a;X-Forwarded-For Header 挂上代理后&#xff1a; 出现以下页面&#xff1a; 先注册一个账户&#xff0c;然后再登录 发现有参数进行传参 发现传参&a…

网站如何有效防止网络攻击

互联网上的网站和应用程序受到各种威胁&#xff0c;如黑客、恶意软件和数据泄漏。因此&#xff0c;了解如何解决网站被攻击的问题至关重要。本文将介绍一些简单的步骤&#xff0c;帮助您提高您的网站的安全性。 确认攻击 要解决网站被攻击的问题&#xff0c;首先需要识别是否遭…

MES管理系统的设计与实施

随着制造业的快速发展&#xff0c;MES生产管理系统逐渐成为企业提高生产效率和管理水平的重要工具。然而&#xff0c;在实施MES管理系统的过程中&#xff0c;如何确保其有效性和可持续性成为了一个亟待解决的问题。本文将从以终为始、自我完善与适应变化三个方面探讨MES管理系统…

数据结构与算法课后题-第五章(树、森林)

1、 2、 3、 4、 5、 6、 7、 8、 9、

Studio One6.5最新版本新增了对Linux的支持

音乐制作人们&#xff0c;这是你们翘首以待的消息。数字音频工作站&#xff08;DAW&#xff09;已经成为音乐制作专业人士重要工具之一。 遗憾的是&#xff0c;对于 Linux 用户而言&#xff0c;选择十分有限。最受欢迎的选择通常是开源 DAW&#xff0c;如 Ardour、Audacity和闭…

SSM - Springboot - MyBatis-Plus 全栈体系(二十九)

第六章 SpringBoot 五、SpringBoot3 整合 MyBatis 1. MyBatis 整合步骤 导入依赖&#xff1a;在您的 Spring Boot 项目的构建文件&#xff08;如 pom.xml&#xff09;中添加 MyBatis 和数据库驱动的相关依赖。例如&#xff0c;如果使用 MySQL 数据库&#xff0c;您需要添加 …

Pulsar Manager配置自定义认证插件访问

Pulsar Manager配置自定义认证插件访问 Pulsar Manager和dashboard部署和启用认证 pulsar自定义认证插件开发 前面博客讲了以token方式访问pulsar 这节博客讲如何配置自定义认证插件的方式访问pulsar #启动pulsar-manager docker run --name pulsar-manager -dit \-p 9527:…

C# Winform编程(3)对话框

C# Winform编程&#xff08;3&#xff09;对话框 Show(string text);Show(string text, string caption);Show(string text, string caption, MessageBoxButtons buttons);Show(string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon); using System;…

UE5发布Android屏幕适配实践(Blueprint)

之前发了一个文章UE5屏幕适配&#xff0c;后续做项目中又遇到问题&#xff0c;对DPI Scale又有了理解&#xff0c;所以又写了这篇文章。https://mp.csdn.net/mp_blog/creation/editor/133337134https://mp.csdn.net/mp_blog/creation/editor/133337134 DPI Scale Rule使用Short…

Linux:将mysql数据导入mongodb

mysql和mongodb都要同时开启 进入mysql创建一个数据库为aaa create database aaa; 创建一个tarro表结构为 &#xff08;id int,name varchar(20)&#xff09; create table tarro(id int,name varchar(20)); 插入几个数据&#xff0c;等会把这里的数据导过去 insert in…

Java多线程解密:揭秘多线程的奥秘,给你全面了解与实践的权威指南

一&#xff1a;进程与线程 概述&#xff1a;几乎任何的操作系统都支持运行多个任务&#xff0c;通常一个任务就是一个程序&#xff0c;而一个程序就是一个进程。当一个进程运行时&#xff0c;内部可能包括多个顺序执行流&#xff0c;每个顺序执行流就是一个线程。 进程&#…

Python学习基础笔记七十二——IDE集成开发环境

集成开发环境&#xff0c;英文缩写是IDE。 IDE可以帮你更高效地开发项目代码。因为它提供了非常实用的功能&#xff0c;比如项目文件管理、语法高亮、代码导航、自动补齐代码、语法静态检查、调试、版本控制等等。 两款IDE&#xff1a;Pycharm和VSCode。 pycharm中的代码文件都…

香港学界呼吁RWA“在港先发”,构建基于港元稳定币的Web3生态!

2023年以来&#xff0c;市场对于RWA&#xff08;Real World Assets&#xff09;即真实世界资产“代币化”的讨论愈发频繁&#xff0c;一些观点认为 RWA将在下一轮加密资产牛市中成为焦点&#xff0c;部分Web3创业者和传统金融企业也快速将业务方向瞄准相关赛道&#xff0c;而被…

Java|学习|异常

1.异常 1.1 异常 1.1.1 概述 异常&#xff1a;就是程序出现了不正常的情况。 Error&#xff1a;严重问题&#xff0c;不需要处理。 Exception&#xff1a;称为异常类&#xff0c;它表示程序本身可以处理的问题。 RuntimeException&#xff1a;在编译器不检查&#xff0c;出…

WorkPlus即时通讯办公软件,助力企业实现移动化办公

在移动互联网的时代背景下&#xff0c;企业对于高效的移动平台需求日益迫切。WorkPlus作为领先品牌&#xff0c;致力于为企业打造卓越的移动平台&#xff0c;助力企业实现协作与效率的突破。本文将探讨WorkPlus如何通过其专业的解决方案&#xff0c;为企业打造无限可能的移动办…

高级系统架构设计师_笔记_真题

2020 科目一 位示图的计算 分页管理-页式存储 软件系统的文档可以分为用户文档和系统文档两类。软件活动&#xff1a; 对应软件开发的各种活动&#xff0c;软件开发工具包括&#xff1a;需求分析工具、设计工具、编码和排错工具、测试工具等。按需求描述定义的方法可将需求分…

day35

今日内容概要 Socket抽象层(socket编程) 基于TCP协议的借助socket可以编程客户端和服务端的程序 链接循环 通信循环 基于UDP协议的套接字(socket)编程 粘包现象 如何解决粘包现象(重要的是解决的思路) struct模块的使用(打包、解包) 今日内容详细 Socket抽象层&#x…

论文阅读:Rethinking Range View Representation for LiDAR Segmentation

来源ICCV2023 0、摘要 LiDAR分割对于自动驾驶感知至关重要。最近的趋势有利于基于点或体素的方法&#xff0c;因为它们通常产生比传统的距离视图表示更好的性能。在这项工作中&#xff0c;我们揭示了建立强大的距离视图模型的几个关键因素。我们观察到&#xff0c;“多对一”…

Linux:mongodb数据库基础操作(3.4版本)

安装 3.*版本和4.*版本安装都是一样的 Linux&#xff1a;mongodb数据库源码包安装&#xff08;4.4.25版本&#xff09;_鲍海超-GNUBHCkalitarro的博客-CSDN博客https://blog.csdn.net/w14768855/article/details/133826626?spm1001.2014.3001.5501 mysql和mongodb对比 登录…