2017-08-31 259 views

回答

1

这些是两个独立因素:size指示原始大小,align只是分配块的位置。在实际的代码中你可能会看到一个关联,你想要某种对齐的原因通常是因为size是某个因素的偶数倍,但这并不是一个硬性要求。

您可能有一个完全有效的理由来分配79个字节对齐在8个字节的基础上。

+0

对此有何参考? –

+0

鉴于未定义的行为非常重要,所以在相关时总会提到它(例如,使指针无效),以及在该函数的文档中没有提及它,因此没有理由相信未定义行为是一个因素。这只是一个分配器,没有什么奇特的。如果你想分配一些非常奇怪的东西,那不是未定义的行为,但是如果你在其中放置了错误对齐的结构,它可能会导致未定义的行为。 – tadman

1

英特尔的文档_mm_mallocin their own compiler只说“这[对齐]约束必须是2的幂”。

没有要求大小为对齐的倍数,因为它的主要用例是SIMD,分配数组的对齐大于单个成员的宽度是完全正常的。 (例如,对于AVX,对应于32B的float*)。或者用于缓存行/页面/巨大页面的边界。例如为了更好地利用透明的巨大页面,您可以为大于2MB的分配使用2MB对齐方式进行分配。

唯一对齐分配器我所知道的是确实有你担心的限制是C11/C++17 aligned_alloc,这是不幸的是在需要时size % align != 0失败。在How to solve the 32-byte-alignment issue for AVX load/store operations?上查看我的回答。 TL; DR:最初的C11 aligned_alloc是具有非多对齐大小的UB,所以真实的实现选择使其如同其他对齐的分配器一样工作(例如posix_memalign)。但是后来它被更改为要求在这种情况下失败(返回一个错误),而不是UB,所以允许它工作的实现在技术上违反了(愚蠢的)标准。 C++ 17具有要求失败的版本。

很显然,英特尔并没有犯与标准委员会所做的aligned_alloc相同的错误,因为它会打败_mm_malloc优化的目的。当然,他们考虑了SIMD和内存边界的使用情况。 (IDK的标准委员会如何不是,它看起来非常明显,它们是类型/缓冲区的主要用例,它比最宽类型的自然对齐更具有对齐性。真正令人失望的是,具有最佳API的一个函数并不安全使用。(aligned_alloc回报内存freeable与free,并且不采取指针的地址,像posix_memalign输入(这会导致编译器担心别名)击败优化。)

还是会分配下一个比较大的字节数是多少?

这对32B或64B等小对齐可能有效。根据具体实施情况,它可能不会将最后的松散空间用于较小的分配,其中malloc或较小的对齐呼叫_mm_malloc。读取对齐边界没有错误(如果它小于4k页面)是安全的,但如果没有明确分配它,则不要写入它。

在任何高质量的实现中,大型对齐会浪费多个整个页面是极不可能的。您总是可以通过执行大量分配(如_mm_malloc(3M, 2M))和一些可以使用该分配空间(如_mm_malloc(512k, 4k)),然后sleep(100)的分配来进行测试。在退出之前查看进程的内存占用情况。

相关问题