[請益] memory aligment

作者: suscym (DoDreamEr)   2020-11-05 14:37:24
大家好,最近針對對齊部分想進一步了解
在stackoverflow上看到這個問題
The memset_16aligned function requires a 16-byte aligned pointer passed to it,
or it will crash.
a) How would you allocate 1024 bytes of memory, and align it to a 16 byte
boundary?
b) Free the memory after the memset_16aligned has executed.
Ans:
{
void *mem = malloc(1024+15);
void *ptr = ((uintptr_t)mem+15) & ~ (uintptr_t)0x0F;
memset_16aligned(ptr, 0, 1024);
free(mem);
}
==============================
題目有人講意思講的不精確,應該講塞的下1024B且對移16Byte~
我這邊想問兩個問題請教
(1) 為何malloc(1024"+15")? 看網站上是說要確定size足夠
但是1024本身不是已經是足夠的嗎?
(2) ((uintptr_t)mem+15) & ~ (uintptr_t)0x0F;
這部分我有看到wiki也是這樣列公式,但是自己待一些16進位位置還是感覺不大
我自己第一個想法是mem+16 & ~.... , 雖然也是可行
但大家說15就足夠,這部分是為什麼呢?
以上請大家指教 3Q
作者: bcew (bcew)   2020-11-05 15:00:00
這是假設malloc得到的起點會亂飄,要用&(~(0xF))修成16 bytealigned,在修的過程最多只會減15而已0x123F & (~(0xF)) =0x1230
作者: suscym (DoDreamEr)   2020-11-05 15:19:00
那請問為何size部分 1024要+15呢
作者: maik060 (^.< 啾咪 ~)   2020-11-05 15:49:00
若mem指到0x1231, 而ptr要對齊的位置是0x1240, 多用了15所以一開始size就多要了15byes, 不然會爆掉 ?
作者: KaryuuIssen (一閃)   2020-11-05 16:13:00
因為你+16可能會浪費16bytes 如同上面兩位舉的例子:(0x1230+16)&(~ 0xF)=0x1240 但0x1230本身就已符合
作者: ucrxzero (RX-0)   2020-11-05 18:15:00
Upbound公式是(byte+align-1)/alignLowerbound公式是byte/align&~0x0F就是強制對齊16+16回錯啦會你少考慮了原本就是16進位的狀況*16對齊簡單來說就是取upbound 的概念 這題就沒問題了lowerbound可能會導致ptr小於mem所以一定是取upperbound是說先別管我最前面兩推的公式,只是感覺那很重要你以後一定會遇到
作者: bcew (bcew)   2020-11-05 18:39:00
如前面m大說的,要確保修正後的ptr,指向的1024B都是自己malloc的,就是先多要15,ptr+15後再用&修正(扣掉不align部分)
作者: ucrxzero (RX-0)   2020-11-05 18:39:00
而且答案其實沒有考慮到最尾巴(多出來尾部使用) 的padding部分只是我最前面upperbound用除法這題用NAND而已更正 clear flag其實答案沒處理結尾padding的處理讓人有點解一半的感覺
作者: wulouise (在線上!=在電腦前)   2020-11-05 19:55:00
可以順便貼原始link嗎?
作者: bcew (bcew)   2020-11-05 21:34:00
有點好奇u大的沒處理padding是什麼,function用ptr,free用mem,應該是沒overflow也沒leak。
作者: ucrxzero (RX-0)   2020-11-05 22:10:00
不是upperbound是rounddown才對= = C++STL用太多了SORRY*roundupto bcew : 這樣會浪費一點點最後的空間是round-up round-down才對 ==破英文to bcew: 不會怎麼樣 但是 那個多出來的空間不會被mark不會被使用是不是有寫法讓padding也是16對齊??這個才對吧我想要不然樓主找的答案會浪費很多空間,那為啥我不要直接分配 2048就好 爽到爆~同意?網路差 打字一職片段
作者: Bencrie   2020-11-05 23:00:00
不是有 posix_memalign 可以用?
作者: taffy128s (imcorn)   2020-11-05 23:04:00
一串未16-byte aligned 的空間 有可能頭多1尾多15頭多2尾多14...頭多15尾多1最壞情況是頭多15尾多1 對吧所以我無論如何 只要補15讓尾巴變16開頭位址再 & ~0x0F 就可以了 是吧
作者: ucrxzero (RX-0)   2020-11-05 23:06:00
對對對你說的都對就是 round-up而已= =
作者: bcew (bcew)   2020-11-05 23:09:00
to u大:要滿足起點對齊16B,總量1024B,使用1039B滿足需求,不管什麼組合都是前後共15B沒用到,我覺得已經是最小浪費了,用更小的空間就有某條件不能滿足。
作者: taffy128s (imcorn)   2020-11-05 23:11:00
恩恩 不用這摸激動 我只是提出另一個講法 看看能不能幫助原po
作者: ucrxzero (RX-0)   2020-11-05 23:12:00
我本來是想說分配的時候就決定結尾突然想到這是OS的事情很棒GOOD
作者: bcew (bcew)   2020-11-05 23:14:00
果然是有誤會^^
作者: wulouise (在線上!=在電腦前)   2020-11-05 23:18:00
原本SO問題的答案很詳細,有另外提到aligned_alloc 可用
作者: Apache (阿帕契)   2020-11-06 00:04:00
大師
作者: suscym (DoDreamEr)   2020-11-06 09:51:00
那實作上 似乎可以先判斷+15前本身是否已是16的倍數 是的話就可以不用做後面的事 省時間省memory(不用多配15) 這樣對嗎? 還是其實多了這判斷反而不會比較有效率
作者: ucrxzero (RX-0)   2020-11-06 10:11:00
你跟我錯一樣的地方欸你要怎麼確認配的mem是16倍數 那時候malloc都配完了 原子操作(malloc)就是不讓你這樣子那你無限迴圈malloc free 到mem有16對齊好了 我記得linux是 best fit 只能慢慢等
作者: CoNsTaR ((const *))   2020-11-06 13:21:00
realloc 的成本和 +15 的成本二選一而已啊
作者: ucrxzero (RX-0)   2020-11-06 13:36:00
作者: wulouise (在線上!=在電腦前)   2020-11-07 08:47:00
我記得gnu是alloc一定會給alingned過的
作者: ucrxzero (RX-0)   2020-11-07 11:04:00
我也覺得奇怪

Links booklink

Contact Us: admin [ a t ] ucptt.com