# 2020q1 Homework3 (quiz4) contributed by < `StevenChen8759` > ###### tags: `linux2020` > [quiz4 題目說明](https://hackmd.io/@sysprog/linux2020-quiz4) ## :Camera: 測驗一 - bitcpy ### :camera_with_flash: 運作原理與填答 * 觀察下列函式 `bitcpy` 的操作,可發現在寫入位址的操作計算上採用了位元運算。 ```cpp=19 size_t read_lhs = _read & 7; // Perform _read mod 8 in bitwise operation size_t read_rhs = 8 - read_lhs; // Get bit position offset in a uint8_t space const uint8_t *source = _src + (_read / 8); // Offset to assigned array position for reading src size_t write_lhs = _write & KK1; // Perform _write mod 8 in bitwise operation size_t write_rhs = 8 - write_lhs; // Get bit position offset in a uint8_t space uint8_t *dest = _dest + (_write / 8); // Offset to assigned array position for writing dest ``` * 函式 `bitcpy` 會將 `source` 之第0個位元算起偏移 `_read` 個位元,複製 `_count` 個位元到`dest` 之第0個位元算起偏移 `_write` 個位元 * 因為儲存位元的資料型態為 `uint8_t` ,每一個陣列欄位為 8 bits ,因此在**陣列元素的欄位偏移**為 `_write` 值除以 8,而**陣列元素內的位元偏移**則為 `_write` 取餘數8,其操作等價於取 `_write` 的最低 3 位元,故填答 `KK1` 之值為 7。 ```cpp=1 #define KK1 7 ``` * 我們接著分析實作位元複製的迴圈,其程式碼實現如下: ```cpp=53 /* Copy all bits in number _count */ while (_count > 0) { // Read data from source and move to next position data = *source++; bitsize = (_count > 8) ? 8 : _count; // Set Operating bit size // Bit offset in uint8_t space is not zero if (read_lhs > 0) { data <<= read_lhs; // Align to position zero if (bitsize > read_rhs) // If tailed reading bits in the next position of array data |= (*source >> read_rhs); // Concate these bit into current position of array } // Reading bit size is smaller than 8, mask bits which are not necessary if (bitsize < 8) data &= read_mask[bitsize]; // Assign data before writing to variable original original = *dest; // Bit offset in uint8_t space is not zero if (write_lhs > 0) { // Assign read mask for leading 0~8 bits mask = read_mask[write_lhs]; // Writing bits is crossing two elements in array if (bitsize > write_rhs) { // Mask bits in front of start position, and write available bits started from offset *dest++ = (original & mask) | (data >> write_lhs); // Write bits which cannot write into previous position original = *dest & write_mask[bitsize - write_rhs]; // Move written bits to correct position *dest = original | (data << write_rhs); } else { // For writing position is not started from zero case, adjust mask for writing bits if ((bitsize - write_lhs) > 0) mask = mask | write_mask[8 - (bitsize - write_lhs)]; // Assign data with mask and concate data if necessary *dest++ = (original & mask) | (data >> write_lhs); } } else { // Mask data output while uint8_t is not fully written if (bitsize < 8) data = data | (original & write_mask[bitsize]); // Data assignment *dest++ = data; } _count -= KK2; // Write bitsize bits for each iteration, minus bitsize } ``` * ### :camera_with_flash: 原始程式碼效能改善 ### :camera_with_flash: 考慮 `Alignment` 以及 `Word Size` 之效能改善 ### :camera_with_flash: Linux 原始碼中的運用 `bitcpy` 技巧的場合 ## :camera: 測驗二 - Vector ### :camera_with_flash: 運作原理與填答 ### :camera_with_flash: 程式效率分析 ### :camera_with_flash: 實作上限制與改善方案 ### :camera_with_flash: 基於上述程式實現 `folly::fbvector` 中的經典操作