C++多線程-chap3 多線程異步和通信-2

這裏,只是記錄自己的學習筆記。

順便和大家分享多線程的基礎知識。然後從入門到實戰。有代碼。

知識點來源:

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


 

C++11 實現base16,並與單線程進行性能測試

 

  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 }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章