這裏,只是記錄自己的學習筆記。
順便和大家分享多線程的基礎知識。然後從入門到實戰。有代碼。
知識點來源:
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 }