# 2019-06-03 方鈺學 ## Q1: 假設 cacheline 是 16B,且在 x86_64 架構,改寫下方程式以降低記憶體操作的成本 ```cpp /* zero-v1.c */ #include <stdbool.h> bool mem_is_zero(const void *data, size_t length) { const unsigned char *p = data; while (length) { if (*p) return false; p++; length--; } return true; } ``` Hint: [strlen 的最佳化](https://hackmd.io/s/BkRKhQGae#%E9%81%8B%E7%94%A8-bit-wise-operator) => ```cpp #include <stdbool.h> #define detect(X)(((X) - 0x01010101) & ~(X) & 0x80808080) bool mem_is_zero(const void *data, size_t length) { const unsigned char *p = data; while(length){ p += if(!detect) } } ``` :notes: 考慮以下: ```cpp /* zero-v2.c */ bool mem_is_zero(const void *data, size_t length) { const uint8_t *p = data; const uint64_t zero[2] = { 0 }; size_t pre = (size_t) (p) & (sizeof(zero) − 1); if (pre) { if (memcmp(p, &zero, length) != 0) return false; p += length; } while (length > sizeof(zero)) { if ((*(uint64_t *) p ) != zero) return false; p += (sizeof(zero)); length -= (sizeof(zero)); } return memcmp(&zero, p, length) == 0; } ``` --- ## Q2: 透過 Linux 核心的 linked list APIs,給定 head,找出 list 內數值最大的節點。假設節點內的數值都是正整數 => ```cpp struct listitem { int i; struct list_head list; }; int find_largest(struct list_head *head){ int n = 0; struct list_head* pos = NULL; pos = head->next; list_for_each(pos ,head){ if(n < list_entry(pos,struct listitem, list)->i) n = list_entry(pos,struct listitem, list)->i; } return n; } ``` --- ## Q3: 承 Q2,將給定的 list 中數值最大的節點移除 Hint: 要考慮到 head 本身就是最大數值的狀況 ```cpp void cut_largest(struct list_head *head) { struct list_head* pos = head -> next; struct list_head* target = head ->next; list_for_each(pos,head){ if(list_entry(target, struct listitem, list)-> i < list_entry(pos, struct listitem, list)->i ) target = pos; } struct list_head** node = &head -> next; while(*node != target) node = &(*node)->next; *node = target -> next; } ``` ---