[请益] 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