---
tags: Linux核心設計/實作
---
# 2023q1 Homework2 (quiz2)
contributed by < DotandLog >
> [題目](https://hackmd.io/@sysprog/linux2023-quiz2)
### 測驗 `1`
補完以下程式碼:
```c =
uint64_t next_pow2(uint64_t x)
{
x |= x >> 1;
x |= x >> 1;
x |= x >> 1;
x |= x >> 1;
x |= x >> 1;
x |= x >> 1;
x |= x >> 1;
x |= x >> AAAA;
x |= x >> 16;
x |= x >> BBBB;
return CCCC;
}
```
```AAAA```:8
```BBBB```:32
```CCCC```:x + 1
#### 延伸問題:
1. 解釋上述程式碼原理,並用[__builtin_clzl](https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html) 改寫
```c
uint64_t next_pow2(uint64_t x)
{
int shift = __builtin_clzl(x);
return 1 << (64 - shift);
}
```
2. 在 Linux 核心原始程式碼找出類似的使用案例並解釋
3. 當上述 clz 內建函式已運用時,編譯器能否產生對應的 x86 指令?
### 測驗 `2`
補完以下程式碼:
```c =
int concatenatedBinary(int n)
{
const int M = 1e9 + 7;
int len = 0; /* the bit length to be shifted */
/* use long here as it potentially could overflow for int */
long ans = 0;
for (int i = 1; i <= n; i++) {
/* removing the rightmost set bit
* e.g. 100100 -> 100000
* 000001 -> 000000
* 000000 -> 000000
* after removal, if it is 0, then it means it is power of 2
* as all power of 2 only contains 1 set bit
* if it is power of 2, we increase the bit length
*/
if (!(DDDD))
len++;
ans = (i | (EEEE)) % M;
}
return ans;
}
```
```DDDD```:(i & (i - 1))
```EEEE```:(ans << len)
#### 延伸問題:
1. 解釋上述程式碼運作原理
2. 嘗試使用__builtin_{clz,ctz,ffs}改寫,並改進運算
### 測驗 `3`
補完以下程式碼:
```c =
size_t swar_count_utf8(const char *buf, size_t len)
{
const uint64_t *qword = (const uint64_t *) buf;
const uint64_t *end = qword + len >> 3;
size_t count = 0;
for (; qword != end; qword++) {
const uint64_t t0 = *qword;
const uint64_t t1 = ~t0;
const uint64_t t2 = t1 & 0x04040404040404040llu;
const uint64_t t3 = t2 + t2;
const uint64_t t4 = t0 & t3;
count += __builtin_popcountll(t4);
}
count = (1 << AAAA) * (len / 8) - count;
count += (len & BBBB) ? count_utf8((const char *) end, len & CCCC) : DDDD;
return count;
}
```
```AAAA```:3
```BBBB```:7
```CCCC```:7
```DDDD```:0
#### 延伸問題:
### 測驗 `4`
補完下列程式碼:
```c =
bool is_pattern(uint16_t x)
{
const uint16_t n = EEEE;
return (n ^ x) < FFFF;
}
```
```EEEE```:x
```FFFF```:x
#### 延伸問題: