作者suscym (DoDreamEr)
看板Soft_Job
标题[请益] memory aligment
时间Thu Nov 5 14:37:24 2020
大家好,最近针对对齐部分想进一步了解
在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://webptt.com/cn.aspx?n=bbs/Soft_Job/M.1604558246.A.579.html
1F:→ bcew: 这是假设malloc得到的起点会乱飘,要用&(~(0xF))修成16 byte 11/05 15:00
2F:→ bcew: aligned,在修的过程最多只会减15而已0x123F & (~(0xF)) = 11/05 15:00
3F:→ bcew: 0x1230 11/05 15:00
4F:→ suscym: 那请问为何size部分 1024要+15呢 11/05 15:19
5F:推 maik060: 若mem指到0x1231, 而ptr要对齐的位置是0x1240, 多用了15 11/05 15:49
6F:→ maik060: 所以一开始size就多要了15byes, 不然会爆掉 ? 11/05 15:50
7F:推 KaryuuIssen: 因为你+16可能会浪费16bytes 如同上面两位举的例子: 11/05 16:13
8F:→ KaryuuIssen: (0x1230+16)&(~ 0xF)=0x1240 但0x1230本身就已符合 11/05 16:14
9F:推 ucrxzero: Upbound公式是(byte+align-1)/align 11/05 18:15
10F:→ ucrxzero: Lowerbound公式是byte/align 11/05 18:17
11F:→ ucrxzero: &~0x0F就是强制对齐16 11/05 18:19
12F:→ ucrxzero: +16回错啦 11/05 18:19
13F:→ ucrxzero: 会 11/05 18:19
14F:→ ucrxzero: 你少考虑了原本就是16进位的状况 11/05 18:20
15F:→ ucrxzero: *16对齐 11/05 18:20
16F:推 ucrxzero: 简单来说就是取upbound 的概念 这题就没问题了 11/05 18:27
17F:→ ucrxzero: lowerbound可能会导致ptr小於mem 11/05 18:28
18F:→ ucrxzero: 所以一定是取upperbound 11/05 18:28
19F:→ ucrxzero: 是说先别管我最前面两推的公式,只是感觉那很重要你以 11/05 18:29
20F:→ ucrxzero: 後一定会遇到 11/05 18:29
21F:→ bcew: 如前面m大说的,要确保修正後的ptr,指向的1024B都是自己mal 11/05 18:39
22F:→ bcew: loc的,就是先多要15,ptr+15後再用&修正(扣掉不align部分) 11/05 18:39
23F:推 ucrxzero: 而且答案其实没有考虑到最尾巴(多出来尾部使用) 的pa 11/05 18:39
24F:→ ucrxzero: dding部分 11/05 18:39
25F:→ ucrxzero: 只是我最前面upperbound用除法这题用NAND而已 11/05 18:40
26F:→ ucrxzero: 更正 clear flag 11/05 18:41
27F:→ ucrxzero: 其实答案没处理结尾padding的处理让人有点解一半的感觉 11/05 18:43
28F:→ ucrxzero: 是说我最前面两推的公式是整数除法喔(无条件舍去 11/05 18:45
29F:推 ucrxzero: 阿靠腰我前面的两个公式忘记还要乘以align 11/05 18:47
30F:→ ucrxzero: 不过概念对就好 11/05 18:47
31F:推 ucrxzero: 重点就是取16的upbound 其他都不用管 11/05 18:51
32F:推 wulouise: 可以顺便贴原始link吗? 11/05 19:55
https://stackoverflow.com/questions/381244/purpose-of-memory-alignment
33F:→ bcew: 有点好奇u大的没处理padding是什麽,function用ptr,free用m 11/05 21:34
34F:→ bcew: em,应该是没overflow也没leak。 11/05 21:34
35F:推 ucrxzero: 不是upperbound是rounddown才对= = C++STL用太多了SORRY 11/05 22:10
36F:→ ucrxzero: *roundup 11/05 22:10
37F:→ ucrxzero: to bcew : 这样会浪费一点点最後的空间 11/05 22:11
38F:→ ucrxzero: 是round-up round-down才对 == 11/05 22:11
39F:推 ucrxzero: 破英文 11/05 22:14
40F:推 ucrxzero: to bcew: 不会怎麽样 但是 那个多出来的空间不会被mark 11/05 22:25
41F:→ ucrxzero: 不会被使用 11/05 22:25
42F:→ ucrxzero: 是不是有写法让padding也是16对齐??这个才对吧我想 11/05 22:26
43F:→ ucrxzero: 要不然楼主找的答案会浪费很多空间,那为啥我不要直接分 11/05 22:26
44F:→ ucrxzero: 配 2048就好 爽到爆~ 11/05 22:26
45F:→ ucrxzero: 同意? 11/05 22:26
46F:→ ucrxzero: 网路差 打字一职片段 11/05 22:27
47F:推 ucrxzero: 是说我错了 因为分配完才知道mem的起始位置~ 11/05 22:59
48F:→ ucrxzero: 以上都当我放屁 11/05 22:59
49F:推 Bencrie: 不是有 posix_memalign 可以用? 11/05 23:00
50F:推 taffy128s: 一串未16-byte aligned 的空间 有可能 11/05 23:04
51F:→ taffy128s: 头多1尾多15 11/05 23:04
52F:→ taffy128s: 头多2尾多14 11/05 23:04
53F:→ taffy128s: ... 11/05 23:04
54F:→ taffy128s: 头多15尾多1 11/05 23:04
55F:→ taffy128s: 最坏情况是头多15尾多1 对吧 11/05 23:04
56F:→ taffy128s: 所以我无论如何 只要补15让尾巴变16 11/05 23:04
57F:→ taffy128s: 开头位址再 & ~0x0F 就可以了 是吧 11/05 23:04
58F:推 ucrxzero: 对对对你说的都对 11/05 23:06
59F:→ ucrxzero: 就是 round-up而已= = 11/05 23:08
60F:→ bcew: to u大:要满足起点对齐16B,总量1024B,使用1039B满足需求, 11/05 23:09
61F:→ bcew: 不管什麽组合都是前後共15B没用到,我觉得已经是最小浪费了 11/05 23:09
62F:→ bcew: ,用更小的空间就有某条件不能满足。 11/05 23:09
63F:推 taffy128s: 恩恩 不用这摸激动 我只是提出另一个讲法 看看能不能帮 11/05 23:11
64F:→ taffy128s: 助原po 11/05 23:11
65F:推 ucrxzero: 我本来是想说分配的时候就决定结尾突然想到这是OS的事情 11/05 23:12
66F:→ ucrxzero: 很棒GOOD 11/05 23:12
67F:→ bcew: 果然是有误会^^ 11/05 23:14
68F:推 wulouise: 原本SO问题的答案很详细,有另外提到aligned_alloc 可用 11/05 23:18
69F:推 Apache: 大师 11/06 00:04
感谢大家热烈的解答~ 高手真多
不然这部分网路上几乎都是外国的讨论
※ 编辑: suscym (114.137.100.199 台湾), 11/06/2020 08:52:44
70F:→ suscym: 那实作上 似乎可以先判断+15前本身是否已是16的倍数 是的 11/06 09:51
71F:→ suscym: 话就可以不用做後面的事 省时间省memory(不用多配15) 这 11/06 09:52
72F:→ suscym: 样对吗? 还是其实多了这判断反而不会比较有效率 11/06 09:52
73F:推 ucrxzero: 你跟我错一样的地方欸你要怎麽确认配的mem是16倍数 那 11/06 10:11
74F:→ ucrxzero: 时候malloc都配完了 原子操作(malloc)就是不让你这样子 11/06 10:11
75F:推 ucrxzero: 那你无限回圈malloc free 到mem有16对齐好了 我记得lin 11/06 10:17
76F:→ ucrxzero: ux是 best fit 只能慢慢等 11/06 10:17
77F:推 CoNsTaR: realloc 的成本和 +15 的成本二选一而已啊 11/06 13:21
78F:推 ucrxzero: 怕 11/06 13:36
79F:推 wulouise: 我记得gnu是alloc一定会给alingned过的 11/07 08:47
80F:推 ucrxzero: 我也觉得奇怪 11/07 11:04