提供されたコメントに関して、以下のコードを理解できません。このコードは何をしますか? と同等のコードは8-aligned
何ですか?
/* segment size must be 4-aligned */
attr->options.ssize &= ~3;
ここでssize
は、unsigned int
タイプです。
提供されたコメントに関して、以下のコードを理解できません。このコードは何をしますか? と同等のコードは8-aligned
何ですか?
/* segment size must be 4-aligned */
attr->options.ssize &= ~3;
ここでssize
は、unsigned int
タイプです。
バイナリの4は100であるため、4バイト境界に揃えられた値(つまり、4の倍数)では、最後の2ビットがゼロに設定されます。
バイナリの3は11であり、〜3はそれらのビットのビット単位の否定、つまり...1111100です。その値でビットごとのANDを実行すると、クリアされる最後の2つ(ビット&1 ==ビット、およびビット&0 == 0)を除いて、すべてのビットが同じに保たれます。これにより、4の倍数である次の低い値または等しい値が得られます。
8(バイナリで1000)に対して同じ操作を行うには、下位3ビットをクリアする必要があります。これは、バイナリ111のビット単位の否定、つまり〜7を使用して行うことができます。
2 のすべてのべき乗 (1、2、4、8、16、32...) は、単純な a and 操作で整列できます。
これにより、切り捨てられたサイズが得られます。
size &= ~(alignment - 1);
または切り上げたい場合:
size = (size + alignment-1) & ~(alignment-1);
「alignment-1」は、2 の累乗の値である限り、2 の累乗のすぐ下のビットまで「すべて 1」になります。~
すべてのビットを反転するため、0 には 1 を、1 には 0 を取得します。
次の方法で、何かが 2 のべき乗であることを確認できます。
bool power_of_two = !(alignment & (alignment-1))
これは、たとえば次の理由で機能します。
4 = 00000100
4-1 = 00000011
& --------
0 = 00000000
または16の場合:
16 = 00010000
16-1 = 00001111
& --------
0 = 00000000
代わりに 5 を使用すると、次のようになります。
5 = 00000101
4-1 = 00000100
& --------
4 = 00000100
したがって、2 のべき乗ではありません。
おそらくもっとわかりやすいコメントでしょう
/* make segment size 4-aligned
by zeroing two least significant bits,
effectively rounding down */
次に、少なくとも私にとっては、すぐに疑問が頭に浮かびます。サイズの場合、本当に切り捨てるべきですか? 切り上げはより適切ではありません:
attr->options.ssize = (attr->options.ssize + 3) & ~3;
他の回答で既に述べたように、8 アラインするには、3 ビットをゼロにする必要があるため、7
代わりに3
. したがって、関数にすることができます。
unsigned size_align(unsigned size, unsigned bit_count_to_zero)
{
unsigned bits = (1 << bit_count_to_zero) - 1;
return (size + bits) & ~bits;
}
~3
はビットパターン...111100
です。そのパターンでビットごとの AND を実行すると、下位 2 ビットがクリアされます。つまり、最も近い 4 の倍数に切り捨てられます。
~7
8 アラインでも同じことを行います。
このコードは、 の下位 2 ビットssize
がクリアされることを保証し、それssize
が 4 の倍数であることを保証します。8 アラインの同等のコードは次のようになります。
attr->options.ssize &= ~7;
number = number & ~3
数値は、以下の最も近い 4の倍数に丸められます。
例:number
if number is 0,1,2 or 3, the `number` is rounded off to 0
同様にif number is 4,5,6,or 7,
数is rounded off to 4
ただし、これがメモリの配置に関連している場合は、メモリを下方向ではなく上方向に配置する必要があります。