MSVC具有自己的非标准功能_aligned_malloc
,_aligned_realloc
和_aligned_free
。
C ++ 17和C11引入了(std::)aligned_alloc
,其结果可以用free
或realloc
进行 de 分配。但是realloc
不能真正用于重新分配aligned_alloc
返回的内存,因为它不使用 alignment 参数,因此不能保证返回的指针将正确对齐。
我什至找不到任何非标准扩展,它们可以在Microsoft Windows / Visual C ++以外的平台上重新分配对齐的内存(保留对齐)。
我搜索错误吗?还是在POSIX和其他平台上确实没有_aligned_realloc
替代方案?
如果是这样,
aligned_alloc
然后在成功时对旧指针进行memcpy
和free
更好的了?答案 0 :(得分:5)
虽然POSIX(在大多数平台上倾向于充当最低的公分母)没有aligned_realloc
,但确实有aligned_alloc
和memcpy
。因此,您可以非常轻松地实现自己的aligned_realloc
,可以保证使用这些malloc
可以在任何符合posix的合理平台上工作。但是,请注意,没有posix标准方法来获取realloc
'd内存区域的大小。您必须自己进行跟踪。
编辑:有一些空闲时间,所以我将其扩展为回答最常见的批评
正如敏锐的评论者所指出的,我所建议的是realloc
在内部的工作方式。
在后台,您的标准__extern_always_inline float vec4_len(const float *v) {
__m128 vec1 = _mm_load_ps(v);
__m128 xmm1 = _mm_mul_ps(vec1, vec1);
__m128 xmm2 = _mm_hadd_ps(xmm1, xmm1);
__m128 xmm3 = _mm_hadd_ps(xmm2, xmm2);
return sqrtf(_mm_cvtss_f32(xmm3));
}
实现将竭尽全力避免执行上述的malloc和memcpying行为,然后再免费提供。在求助于回退之前,它将尝试使用两种行为之一。
1)如果新的大小小于旧的大小,它将在适当的位置调整内存大小,避免分配,复制或释放内存。
2)如果新的大小大于旧的大小,它将(以简化的方式)查看是否有足够的空闲内存相邻,如果是,它将吞噬该内存并适当调整大小。如果不是,则求助于后备。
我提出了一种幼稚的方法,因为我认为大多数提出这个问题的人都不想实现自己的malloc实现。 (尽管我强烈建议这样做是出于教育目的)
希望这可以满足所有投诉!
答案 1 :(得分:2)
Intel Math Kernel Library(免费;适用于Windows,Linux和macOS)版本。 > = 11.3.1具有mkl_realloc
可以保持对齐:
简单的例子:
auto p1 = std::aligned_alloc(1024, 1000);
std::cout << reinterpret_cast<std::uintptr_t>(p1) % 1024 << std::endl;
auto p2 = std::realloc(p1, 2000);
std::cout << reinterpret_cast<std::uintptr_t>(p2) % 1024 << std::endl;
auto p3 = std::realloc(p2, 3000);
std::cout << reinterpret_cast<std::uintptr_t>(p3) % 1024 << std::endl;
auto q1 = mkl_malloc(1000, 1024);
std::cout << reinterpret_cast<std::uintptr_t>(q1) % 1024 << std::endl;
auto q2 = mkl_realloc(q1, 2000);
std::cout << reinterpret_cast<std::uintptr_t>(q2) % 1024 << std::endl;
auto q3 = mkl_realloc(q2, 3000);
std::cout << reinterpret_cast<std::uintptr_t>(q3) % 1024 << std::endl;
我的机器上的输出是:
0
784
784
0
0
0