15

我正在用 C 语言开发一个项目,它需要 memalign()。确实,posix_memalign() 也可以,但是 darwin/OSX 缺少这两个。

有什么好的解决方案可以解决 memalign 的问题?如果我要撕掉 memalign.c 并将其放入我的项目中,我不了解 posix-C 代码的许可——我不想要任何病毒类型的许可 LGPL-ing 我的整个项目。

4

9 回答 9

13

Mac OS X 似乎是16 字节内存对齐的。

引自网站:

我很难找到关于 MacOS X 内存对齐的明确声明,所以我做了自己的测试。在 10.4/intel 上,堆栈和堆内存都是 16 字节对齐的。所以移植软件的人可以停止寻找 memalign() 和 posix_memalign()。这不是必需的。

于 2008-10-13T00:15:21.320 回答
11

更新:OSX 现在有posix_memalign()

迟到了,但更新版本的 OSX确实posix_memalign(). 在与页面边界对齐时,您可能需要这样做。例如:

#include <stdlib.h>

char *buffer;
int pagesize;

pagesize = sysconf(_SC_PAGE_SIZE);
if (pagesize == -1) handle_error("sysconf");

if (posix_memalign((void **)&buffer, pagesize, 4 * pagesize) != 0) {
  handle_error("posix_memalign");
}

需要注意的一点是,与 不同的是memalign()posix_memalign()**buffer作为参数并返回一个整数错误代码。

于 2014-04-05T04:48:57.187 回答
7

自己做应该很容易,不是吗?类似于以下内容(未测试):

void *aligned_malloc( size_t size, int align )
{
    void *mem = malloc( size + (align-1) + sizeof(void*) );

    char *amem = ((char*)mem) + sizeof(void*);
    amem += align - ((uintptr)amem & (align - 1));

    ((void**)amem)[-1] = mem;
    return amem;
}

void aligned_free( void *mem )
{
    free( ((void**)mem)[-1] );
}

(感谢乔纳森莱弗勒

编辑: 关于扯掉另一个 memalign 实现,问题不在于许可。相反,您会遇到困难,即任何好的 memalign 实现都将成为堆管理器代码库的组成部分,而不是简单地分层在 malloc/free 之上。因此,将它移植到不同的堆管理器时会遇到严重的麻烦,尤其是当您无法访问它的内部时。

于 2008-10-13T00:18:41.970 回答
3

为什么您要移植的软件需要 memalign() 或 posix_memalign()?它是否将它用于比 austirg 引用的 16 字节对齐更大的对齐?

我看到 Mike F 发布了一些代码——它看起来比较简洁,尽管我认为 while 循环可能不是最佳的(如果所需的对齐是 1KB,它可能会迭代很多次)。

不:

amem += align - ((uintptr)amem & (align - 1));

一次手术就能到达那里?

于 2008-10-13T00:31:35.953 回答
2

从 macosx 手册页:

malloc()、calloc()、valloc()、realloc() 和 reallocf() 函数分配内存。分配的内存对齐,以便它可以用于任何数据类型,包括 AltiVec 和 SSE 相关类型。free() 函数释放通过前面的分配函数创建的分配。

于 2008-10-13T11:20:54.800 回答
1

是的,Mac OS X在ABI中确实有 16 字节内存对齐。您不需要使用 memalign()。如果您的内存要求是 16 倍,那么我不会实现它,也许只是添加一个断言。

于 2008-10-13T00:34:11.300 回答
1

如果您需要一个任意对齐的 malloc,请查看 x264 的 malloc(git 存储库中的 common/common.c),它为没有 malloc.h 的系统提供了自定义 memalign。它的代码极其微不足道,以至于我什至不认为它具有版权,但是您在看到它之后应该可以轻松地实现自己的代码。

当然,如果你只需要 16 字节对齐,如上所述,它在 OS X ABI 中。

于 2008-10-13T00:55:31.273 回答
1

可能值得建议在您的代码中使用 Doug Lea 的 malloc。链接文本

于 2009-03-03T08:59:40.697 回答
0

感谢您的帮助,伙计们......在我的情况下有所帮助(OpenCascade src/Image/Image_PixMap.cxx,OSX10.5.8 PPC)

结合上面的答案,如果不是特别熟悉 malloc 等,这可能会节省一些人的挖掘或灌输希望:

我正在构建的相当大的项目只有一个对 posix_memalign 的引用,事实证明这是一堆不包括 OSX 但确实包括 BORLANDC 的预处理器条件的结果,这证实了其他人认为它是安全的在某些情况下使用 malloc:

#if defined(_MSC_VER)
 return (TypePtr )_aligned_malloc (theBytesCount, theAlign);
#elif (defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 1)
 return (TypePtr )     _mm_malloc (theBytesCount, theAlign);
#elif defined(__BORLANDC__)
 return (TypePtr ) malloc (theBytesCount);
#else
 void* aPtr;
 if (posix_memalign (&aPtr, theAlign, theBytesCount))
 {
     aPtr = NULL;
 }
 return (TypePtr )aPtr;
#endif

因此,正如其他人所建议的那样,它可以像使用 malloc 一样简单。

例如这里:在__BORLANDC__上面移动条件__GNUC__并添加APPLE

#elif (defined(__BORLANDC__) || defined(__APPLE__)) //now above `__GNUC__`

注意:我没有上面所说的 OS X 那样检查 BORLANDC 是否使用 16 字节对齐。我也没有验证 PPC OS X 确实如此。然而,这种用法表明这种对齐并不是特别重要。(希望它有效,并且对您的搜索者来说也很容易!)

于 2013-01-29T03:38:32.380 回答