• C++多线程chap3 多线程异步和通信2


    这里,只是记录自己的学习笔记。

    顺便和大家分享多线程的基础知识。然后从入门到实战。有代码。

    知识点来源:

    https://edu.51cto.com/course/26869.html


    C++11 实现base16,并与单线程进行性能测试

    base16编码,解码,请看这篇文章:https://www.cnblogs.com/music-liang/p/15656218.html 

      1 /*
      2 C++17 多核并行计算
      3 
      4 4.1 手动实现多核 base16编码
      5 4.1.1 实现base16编码
      6   1.二进制转换为字符串
      7   2.一个字节8位,拆分为2个4位字节(最大值为16)
      8   3.拆分后的字节映射到 0123456789abcdef
      9 
     10 //不创建线程的情况下通过 foreach 实现多核编码
     11 
     12 */
     13 
     14 
     15 #include <iostream>
     16 #include <thread>
     17 #include <vector>
     18 #include <chrono>
     19 #include <execution>
     20 using namespace std;
     21 
     22 static const char base16[] = "0123456789abcdef";
     23 
     24 //base16编码
     25 void Base16Encode(const unsigned char* data, int size, unsigned char* out)
     26 {
     27     for (int i = 0; i < size; i++) {
     28         unsigned char d = data[i];
     29         //1234 5678 >>4  0000 1234   ,右移4位,取到高位字节
     30         //1234 5678 & 0000 1111   0000 5678,与操作得到低位字节
     31         char a = base16[d >> 4];
     32         char b = base16[d & 0x0F];
     33         out[i * 2] = a;
     34         out[i * 2 + 1] = b;
     35     }
     36 }
     37 
     38 //C++11 多核base16编码
     39 void Base16EncodeThread(const vector<unsigned char>& data, vector<unsigned char> &out)
     40 {
     41     int size = data.size();
     42     int th_count = thread::hardware_concurrency();//系统支持的线程核心数
     43 
     44     //切片数据
     45     int slice_count = size / th_count;//余数丢弃
     46     if (size < th_count) { //只切一片
     47         th_count = 1;
     48         slice_count = size;
     49     }
     50 
     51     //准备好线程
     52     vector<thread> ths;
     53     ths.resize(th_count);
     54 
     55     //任务分配到各个线程
     56     for (int i = 0; i < th_count; i++) {
     57         // 1234 5678 9abc defg hi
     58         int offset = i * slice_count;
     59         int count = slice_count;
     60 
     61         //最后一个线程
     62         if (th_count > 1 && i == th_count - 1) {
     63             count = slice_count + size % th_count;
     64         }
     65         cout << "offset:" << offset << ",count:" << count << endl;
     66 
     67         ths[i] = thread(Base16Encode, data.data() + offset, count, out.data());
     68     }
     69 
     70     for (auto& th : ths) {
     71         th.join();//等待所有线程结束
     72     }
     73     cout << "over" << endl;
     74 }
     75 
     76 
     77 int main()
     78 {
     79     string test_data = "测试base16编码";
     80     unsigned char out[1024] = { 0 };
     81     Base16Encode((const unsigned char*)test_data.data(), test_data.size(), out);
     82     cout << "base16 Encode:" << out << endl;
     83     cout << "char length:" << sizeof(out) / sizeof(unsigned char) << endl;
     84 
     85     vector<unsigned char> in_data;
     86     in_data.resize(1024 * 1024 * 20);//20M
     87     for (int i = 0; i < in_data.size(); i++) {
     88         in_data[i] = i % 256;
     89     }
     90     vector<unsigned char> out_data;
     91     out_data.resize(in_data.size() * 2);
     92 
     93 
     94     //测试单线程 base16 编码效率
     95     {
     96         cout << "单线程 base16  开始计算" << endl;
     97 
     98         auto start = chrono::system_clock::now();
     99         Base16Encode(in_data.data(), in_data.size(), out_data.data());
    100 
    101         auto end = chrono::system_clock::now();
    102         auto duration = chrono::duration_cast<chrono::milliseconds>(end - start);
    103         cout << "编码:"<<in_data.size()<<"字节数据花费 " << duration.count() <<" 毫秒"<<flush<< endl;
    104         //cout << "out_data.data():" << out_data.data() << endl;
    105     }
    106 
    107 
    108     //C++11 多线程Base16编码
    109     {
    110         cout << "C++11 多线程Base16编码 开始计算" << endl;
    111         auto start = chrono::system_clock::now();
    112         Base16EncodeThread(in_data, out_data);
    113         auto end = chrono::system_clock::now();
    114         auto duration = chrono::duration_cast<chrono::milliseconds>(end - start);
    115         cout << "编码:" << in_data.size() << "字节数据花费 " << duration.count() << " 毫秒" << flush << endl;
    116     }
    117 
    118 
    119     //C++17   for_each 写法更加简洁
    120     {
    121         cout << "C++17 多线程Base16编码 开始计算" << endl;
    122         auto start = chrono::system_clock::now();
    123 
    124         // #include <execution> C++17支持
    125         unsigned char* idata = in_data.data();
    126         unsigned char* odata = out_data.data();
    127 
    128         //在release模式下,C++17会更快
    129         std::for_each(std::execution::par,//并行计算 多核
    130             in_data.begin(), in_data.end(),
    131             [&](auto& d) { //多线程进入此函数
    132             char a = base16[(d >> 4)];
    133             char b = base16[(d & 0x0F)];
    134             int index = &d - idata ;//计算偏移位置
    135             odata[index * 2] = a;
    136             odata[index * 2 + 1] = b;
    137         }
    138         );
    139         
    140         auto end = chrono::system_clock::now();
    141         auto duration = chrono::duration_cast<chrono::milliseconds>(end - start);
    142         cout << "编码:" << in_data.size() << "字节数据花费 " << duration.count() << " 毫秒" << flush << endl;
    143     }
    144 
    145 
    146 
    147     getchar();
    148     return 0;
    149 }

     

     

    作者:小乌龟
    【转载请注明出处,欢迎转载】 希望这篇文章能帮到你

     

  • 相关阅读:
    记账本开发记录——第十三天(2020.1.31)
    《构建之法——现代软件工程》读书笔记(二)
    记账本开发记录——第十二天(2020.1.30)
    记账本开发记录——第十一天(2020.1.29)
    记账本开发记录——第十天(2020.1.28)
    记账本开发记录——第九天(2020.1.27)
    记账本开发记录——第八天(2020.1.26)
    记账本开发记录——第七天(2020.1.24)
    记账本开发记录——第六天(2020.1.23)
    记账本开发记录——第五天(2020.1.22)
  • 原文地址:https://www.cnblogs.com/music-liang/p/15643407.html
Copyright © 2020-2023  润新知