目的:
1
在 PLDI'19 論文 Computing Summaries of String Loops in C for Better Testing and Refactoring 提到開發者會希望對 loop summarisation 進行替換,例如 GNU patch 這支程式原本程式碼是:
替換為 GNU extension:
其中 rawmemchr 是自從 glibc-2.1 即提供的擴充函式:
The rawmemchr() function is similar to memchr(): it assumes (i.e., the programmer knows for certain) that an instance of c lies somewhere in the memory area starting at the location pointed to by s, and so performs an optimized search for c (i.e., no use of a count argument to limit the range of the search). If an instance of c is not found, the results are unpredictable. The following call is a fast means of locating a string's terminating null byte:
以下程式碼嘗試運用 你所不知道的C語言:數值系統篇 提及的 Detect NULL 技巧,來加速 rawmemchr
的實作,適用於 32 位元和 64 位元的 little-endian 架構:
請補完程式碼,應要能在 x86_64 架構獲得效能提升。
作答區
AAA = ?
(a)
4(b)
8(c)
16(d)
32(e)
64BBB = ?
(a)
4(b)
8(c)
16(d)
32(e)
64延伸問題:
2
考慮到 cirbuf 這個 circular buffer 實作,嘗試透過 mmap 系統呼叫以化簡緩衝區邊界處理的議題。
為何 circular buffer 初始化時要呼叫三次 mmap 呢?
有了這個特性後,當我們使用 memcpy 在寫入/讀取 buffer 時即可不用考慮到邊界問題,進而改善存取效率,否則,我們必須考慮到目前 index 是否會超出邊界等等,這將對效能造成衝擊,在 Using black magic to make a fast circular buffer 一文指出,這兩種方法的效率差距可達三倍之譜。
對照 cirbuf.h 和 test-cirbuf.c 以得知具體用法,請補完以下程式碼:
作答區
MM1 = ?
(a)
if (cb->size > cb->tail) cb->tail = 0;(b)
if (cb->size < cb->tail) cb->tail = 0;(c)
if (cb->size < cb->tail) cb->tail -= cb->size;(d)
if (cb->size < cb->tail) cb->tail %= cb->size;(e)
if (cb->size < cb->tail) cb->tail++;(f)
if (cb->size < cb->tail) cb->size = 0;MM2 = ?
(a)
return cb->data;(b)
returb cb->head;(c)
returb cb->data + cb->head;(d)
return NULL;延伸問題: