[請益] memory aligment

看板Soft_Job (軟體人)作者 (DoDreamEr)時間5年前 (2020/11/05 14:37), 5年前編輯推噓25(25055)
留言80則, 10人參與, 5年前最新討論串1/1
大家好,最近針對對齊部分想進一步了解 在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 -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 220.128.79.74 (臺灣) ※ 文章網址: https://www.ptt.cc/bbs/Soft_Job/M.1604558246.A.579.html

11/05 15:00, 5年前 , 1F
這是假設malloc得到的起點會亂飄,要用&(~(0xF))修成16 byte
11/05 15:00, 1F

11/05 15:00, 5年前 , 2F
aligned,在修的過程最多只會減15而已0x123F & (~(0xF)) =
11/05 15:00, 2F

11/05 15:00, 5年前 , 3F
0x1230
11/05 15:00, 3F

11/05 15:19, 5年前 , 4F
那請問為何size部分 1024要+15呢
11/05 15:19, 4F

11/05 15:49, 5年前 , 5F
若mem指到0x1231, 而ptr要對齊的位置是0x1240, 多用了15
11/05 15:49, 5F

11/05 15:50, 5年前 , 6F
所以一開始size就多要了15byes, 不然會爆掉 ?
11/05 15:50, 6F

11/05 16:13, 5年前 , 7F
因為你+16可能會浪費16bytes 如同上面兩位舉的例子:
11/05 16:13, 7F

11/05 16:14, 5年前 , 8F
(0x1230+16)&(~ 0xF)=0x1240 但0x1230本身就已符合
11/05 16:14, 8F

11/05 18:15, 5年前 , 9F
Upbound公式是(byte+align-1)/align
11/05 18:15, 9F

11/05 18:17, 5年前 , 10F
Lowerbound公式是byte/align
11/05 18:17, 10F

11/05 18:19, 5年前 , 11F
&~0x0F就是強制對齊16
11/05 18:19, 11F

11/05 18:19, 5年前 , 12F
+16回錯啦
11/05 18:19, 12F

11/05 18:19, 5年前 , 13F
11/05 18:19, 13F

11/05 18:20, 5年前 , 14F
你少考慮了原本就是16進位的狀況
11/05 18:20, 14F

11/05 18:20, 5年前 , 15F
*16對齊
11/05 18:20, 15F

11/05 18:27, 5年前 , 16F
簡單來說就是取upbound 的概念 這題就沒問題了
11/05 18:27, 16F

11/05 18:28, 5年前 , 17F
lowerbound可能會導致ptr小於mem
11/05 18:28, 17F

11/05 18:28, 5年前 , 18F
所以一定是取upperbound
11/05 18:28, 18F

11/05 18:29, 5年前 , 19F
是說先別管我最前面兩推的公式,只是感覺那很重要你以
11/05 18:29, 19F

11/05 18:29, 5年前 , 20F
後一定會遇到
11/05 18:29, 20F

11/05 18:39, 5年前 , 21F
如前面m大說的,要確保修正後的ptr,指向的1024B都是自己mal
11/05 18:39, 21F

11/05 18:39, 5年前 , 22F
loc的,就是先多要15,ptr+15後再用&修正(扣掉不align部分)
11/05 18:39, 22F

11/05 18:39, 5年前 , 23F
而且答案其實沒有考慮到最尾巴(多出來尾部使用) 的pa
11/05 18:39, 23F

11/05 18:39, 5年前 , 24F
dding部分
11/05 18:39, 24F

11/05 18:40, 5年前 , 25F
只是我最前面upperbound用除法這題用NAND而已
11/05 18:40, 25F

11/05 18:41, 5年前 , 26F
更正 clear flag
11/05 18:41, 26F

11/05 18:43, 5年前 , 27F
其實答案沒處理結尾padding的處理讓人有點解一半的感覺
11/05 18:43, 27F

11/05 18:45, 5年前 , 28F
是說我最前面兩推的公式是整數除法喔(無條件捨去
11/05 18:45, 28F

11/05 18:47, 5年前 , 29F
阿靠腰我前面的兩個公式忘記還要乘以align
11/05 18:47, 29F

11/05 18:47, 5年前 , 30F
不過概念對就好
11/05 18:47, 30F

11/05 18:51, 5年前 , 31F
重點就是取16的upbound 其他都不用管
11/05 18:51, 31F

11/05 19:55, 5年前 , 32F
可以順便貼原始link嗎?
11/05 19:55, 32F

11/05 21:34, 5年前 , 33F
有點好奇u大的沒處理padding是什麼,function用ptr,free用m
11/05 21:34, 33F

11/05 21:34, 5年前 , 34F
em,應該是沒overflow也沒leak。
11/05 21:34, 34F

11/05 22:10, 5年前 , 35F
不是upperbound是rounddown才對= = C++STL用太多了SORRY
11/05 22:10, 35F

11/05 22:10, 5年前 , 36F
*roundup
11/05 22:10, 36F

11/05 22:11, 5年前 , 37F
to bcew : 這樣會浪費一點點最後的空間
11/05 22:11, 37F

11/05 22:11, 5年前 , 38F
是round-up round-down才對 ==
11/05 22:11, 38F

11/05 22:14, 5年前 , 39F
破英文
11/05 22:14, 39F

11/05 22:25, 5年前 , 40F
to bcew: 不會怎麼樣 但是 那個多出來的空間不會被mark
11/05 22:25, 40F

11/05 22:25, 5年前 , 41F
不會被使用
11/05 22:25, 41F

11/05 22:26, 5年前 , 42F
是不是有寫法讓padding也是16對齊??這個才對吧我想
11/05 22:26, 42F

11/05 22:26, 5年前 , 43F
要不然樓主找的答案會浪費很多空間,那為啥我不要直接分
11/05 22:26, 43F

11/05 22:26, 5年前 , 44F
配 2048就好 爽到爆~
11/05 22:26, 44F

11/05 22:26, 5年前 , 45F
同意?
11/05 22:26, 45F

11/05 22:27, 5年前 , 46F
網路差 打字一職片段
11/05 22:27, 46F

11/05 22:59, 5年前 , 47F
是說我錯了 因為分配完才知道mem的起始位置~
11/05 22:59, 47F

11/05 22:59, 5年前 , 48F
以上都當我放屁
11/05 22:59, 48F

11/05 23:00, 5年前 , 49F
不是有 posix_memalign 可以用?
11/05 23:00, 49F

11/05 23:04, 5年前 , 50F
一串未16-byte aligned 的空間 有可能
11/05 23:04, 50F

11/05 23:04, 5年前 , 51F
頭多1尾多15
11/05 23:04, 51F

11/05 23:04, 5年前 , 52F
頭多2尾多14
11/05 23:04, 52F

11/05 23:04, 5年前 , 53F
...
11/05 23:04, 53F

11/05 23:04, 5年前 , 54F
頭多15尾多1
11/05 23:04, 54F

11/05 23:04, 5年前 , 55F
最壞情況是頭多15尾多1 對吧
11/05 23:04, 55F

11/05 23:04, 5年前 , 56F
所以我無論如何 只要補15讓尾巴變16
11/05 23:04, 56F

11/05 23:04, 5年前 , 57F
開頭位址再 & ~0x0F 就可以了 是吧
11/05 23:04, 57F

11/05 23:06, 5年前 , 58F
對對對你說的都對
11/05 23:06, 58F

11/05 23:08, 5年前 , 59F
就是 round-up而已= =
11/05 23:08, 59F

11/05 23:09, 5年前 , 60F
to u大:要滿足起點對齊16B,總量1024B,使用1039B滿足需求,
11/05 23:09, 60F

11/05 23:09, 5年前 , 61F
不管什麼組合都是前後共15B沒用到,我覺得已經是最小浪費了
11/05 23:09, 61F

11/05 23:09, 5年前 , 62F
,用更小的空間就有某條件不能滿足。
11/05 23:09, 62F

11/05 23:11, 5年前 , 63F
恩恩 不用這摸激動 我只是提出另一個講法 看看能不能幫
11/05 23:11, 63F

11/05 23:11, 5年前 , 64F
助原po
11/05 23:11, 64F

11/05 23:12, 5年前 , 65F
我本來是想說分配的時候就決定結尾突然想到這是OS的事情
11/05 23:12, 65F

11/05 23:12, 5年前 , 66F
很棒GOOD
11/05 23:12, 66F

11/05 23:14, 5年前 , 67F
果然是有誤會^^
11/05 23:14, 67F

11/05 23:18, 5年前 , 68F
原本SO問題的答案很詳細,有另外提到aligned_alloc 可用
11/05 23:18, 68F

11/06 00:04, 5年前 , 69F
大師
11/06 00:04, 69F
感謝大家熱烈的解答~ 高手真多 不然這部分網路上幾乎都是外國的討論 ※ 編輯: suscym (114.137.100.199 臺灣), 11/06/2020 08:52:44

11/06 09:51, 5年前 , 70F
那實作上 似乎可以先判斷+15前本身是否已是16的倍數 是的
11/06 09:51, 70F

11/06 09:52, 5年前 , 71F
話就可以不用做後面的事 省時間省memory(不用多配15) 這
11/06 09:52, 71F

11/06 09:52, 5年前 , 72F
樣對嗎? 還是其實多了這判斷反而不會比較有效率
11/06 09:52, 72F

11/06 10:11, 5年前 , 73F
你跟我錯一樣的地方欸你要怎麼確認配的mem是16倍數 那
11/06 10:11, 73F

11/06 10:11, 5年前 , 74F
時候malloc都配完了 原子操作(malloc)就是不讓你這樣子
11/06 10:11, 74F

11/06 10:17, 5年前 , 75F
那你無限迴圈malloc free 到mem有16對齊好了 我記得lin
11/06 10:17, 75F

11/06 10:17, 5年前 , 76F
ux是 best fit 只能慢慢等
11/06 10:17, 76F

11/06 13:21, 5年前 , 77F
realloc 的成本和 +15 的成本二選一而已啊
11/06 13:21, 77F

11/06 13:36, 5年前 , 78F
11/06 13:36, 78F

11/07 08:47, 5年前 , 79F
我記得gnu是alloc一定會給alingned過的
11/07 08:47, 79F

11/07 11:04, 5年前 , 80F
我也覺得奇怪
11/07 11:04, 80F
文章代碼(AID): #1VevscLv (Soft_Job)
文章代碼(AID): #1VevscLv (Soft_Job)