Why is there no 'aligned_realloc' on most platforms?

我们两清 提交于 2020-06-12 04:41:56

问题


MSVC has its own non-standard functions _aligned_malloc, _aligned_realloc and _aligned_free.

C++17 and C11 have introduced (std::)aligned_alloc, results of which can be deallocated with free or realloc. But realloc cannot be used to actually reallocate memory returned by aligned_alloc, since it does not take an alignment parameter and thus cannot guarantee that the returned pointer will be properly aligned.

I can't even find any non-standard extensions that could reallocate aligned memory (preserving its alignment) on platforms other than Microsoft Windows / Visual C++.

Am I searching for it wrong, or is there indeed no _aligned_realloc alternative on POSIX and other platforms?

If so,

  1. Why?
  2. What can be used instead on those platforms? Is there nothing better than calling aligned_alloc with the new alignment, and then doing memcpy and freeing the old pointer on success?

回答1:


While POSIX (which tends to act as a lowest common denominator on most platforms) does not have an aligned_realloc, it does have aligned_alloc and memcpy. Therefore you can very easily implement your own aligned_realloc which is guaranteed to work on any reasonably posix compliant platform using these. However, note that there is not a posix standard method to get the size of a malloc'd region of memory. You'll have to track that yourself.

EDIT: have a bit of free time so I'm extending this to answer the most common criticism

What I've proposed is, as the astute commenter will note, not how realloc works internally.

Under the hood, your standard realloc implementation will do its damnedest to avoid preforming the above behavior of mallocing and memcpying with a free afterwards. It will try to use one of two behaviors before resorting to the fallback. 1) If the new size is smaller than the old size, it will resize the memory in place, avoiding having to allocate, copy, or free. 2) if the new size is greater than the old size, it will (in simplified terms) see if there is free memory of sufficient size adjacent, and if so it will gobble up that memory and resize in place. If not, it resorts to the fallback.

I proposed a naive approach, because I figured most people asking this question wouldn't want to have to implement their own malloc implementation. (Though I highly suggest doing such for educational purposes)

Hope this satisfies any complaints!




回答2:


Intel Math Kernel Library (free; available for Windows, Linux and macOS) ver. >= 11.3.1 has mkl_realloc that preserves alignment:

Simple example:

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;

The output on my machine is:

0
784
784
0
0
0


来源:https://stackoverflow.com/questions/56619623/why-is-there-no-aligned-realloc-on-most-platforms

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!