OSX lacks memalign



我正在用C编写一个项目,它需要memalign()。实际上,posix_mealign()也可以,但darwin/OSX两者都不具备。

什么是memalign中shoehorn的好解决方案?如果我要剽窃memalign.C并将其放在我的项目中,我不理解posix-C代码的许可——我不希望在我的整个项目中使用任何病毒型许可LGPL。

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

网站报价:

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

更新: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作为参数,并返回一个整数错误代码。

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

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] );
}

(感谢Jonathan Leffler)

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

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

我看到Mike F发布了一些代码——它看起来相对整洁,尽管我认为while循环可能是次优的(如果需要的对齐是1KB,它可以迭代很多次)。

没有:

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

一次手术就能到达那里?

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

从macosx手册页:

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

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

当然,如果您只需要16字节对齐,如上所述,它在OSXABI中。

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

谢谢大家的帮助。。。在我的案例中有所帮助(OpenCascade src/Image/Image_PixMap.cxx,OSX10.5.8 PPC)

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

我正在构建的这个相当大的项目只有一个对posix_meagn的引用,事实证明这是一系列预处理器条件的结果,这些条件不包括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__`

注意:我检查了BORLANDC是否像上面提到的OS X一样使用16字节对齐。我也没有验证PPC OS X是这样做的。然而,这种用法表明这种对齐并不特别重要。(希望它能起作用,对搜索者来说也能这么容易!)

相关内容

  • 没有找到相关文章

最新更新