私はCでプロジェクトに取り組んでおり、memalign()が必要です。実際には、posix_memalign()も同様に機能しますが、darwin/OSXには両方がありません。
靴べらの良い解決策は何ですか?memalign.cを取り除いてプロジェクトに入れるとしたら、posix-Cコードのライセンスがわかりません。プロジェクト全体にウイルスタイプのライセンスをLGPLで使用したくありません。
MacOSXは16バイトのメモリに対応しているようです。
ウェブサイトからの引用:
MacOS Xのメモリアライメントに関する決定的なステートメントを見つけるのに苦労したので、自分でテストを行いました。10.4 / Intelでは、スタックメモリとヒープメモリの両方が16バイトに整列されます。したがって、ソフトウェアを移植する人々は、memalign()とposix_memalign()を探すのをやめることができます。必要ありません。
自分でやるのは簡単なはずですよね?次のようなもの(テストされていません):
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の上に単純に階層化されるのではなく、ヒープマネージャーのコードベースの不可欠な部分になるという困難に直面するでしょう。そのため、特に内部にアクセスできない場合は、別のヒープマネージャーに移植するのに深刻な問題が発生します。
移植するソフトウェアにmemalign()またはposix_memalign()が必要なのはなぜですか?austirgによって参照される16バイトのアラインメントよりも大きいアラインメントに使用しますか?
Mike Fがいくつかのコードを投稿しているのがわかります。whileループは最適ではないと思いますが、比較的きれいに見えます(必要な配置が1KBの場合、かなりの回数繰り返される可能性があります)。
しません:
amem += align - ((uintptr)amem & (align - 1));
1回の操作でそこに着きますか?
macosxのマニュアルページから:
malloc()、calloc()、valloc()、realloc()、およびreallocf()関数はメモリを割り当てます。割り当てられたメモリは、AltiVecおよびSSE関連のタイプを含むすべてのデータタイプで使用できるように調整されます。free()関数は、前述の割り当て関数を介して作成された割り当てを解放します。
はい、Mac OS XのABIには 16 バイトのメモリ アラインメントがあります。memalign() を使用する必要はありません。メモリ要件が 16 倍である場合、私はそれを実装せず、アサートを追加するだけです。
任意にアラインされた malloc が必要な場合は、x264 の malloc (git リポジトリの common/common.c) を調べてください。これには、malloc.h のないシステム用のカスタム memalign があります。非常に些細なコードで、著作権で保護されているとは思えませんが、見れば簡単に独自のコードを実装できるはずです。
もちろん、上記のように 16 バイトのアラインメントのみが必要な場合は、OS X ABI に含まれています。
助けてくれてありがとう、みんな...私の場合は助けてくれた(OpenCascade src/Image/Image_PixMap.cxx、OSX10.5.8 PPC)
上記の回答と組み合わせると、mallocなどに特に精通していない場合でも、誰かが掘り下げたり、希望を植え付けたりするのを防ぐことができます。
私が構築しているかなり大規模なプロジェクトには、posix_memalign への参照が 1 つしかありませんでした。それは、OSX を含まないが DID に 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__
上記の条件を移動し、 APPLE__GNUC__
を追加:
#elif (defined(__BORLANDC__) || defined(__APPLE__)) //now above `__GNUC__`
注:上記の誰かが OS X で行っているように、BORLANDC が 16 バイト アラインメントを使用していることを確認していません。また、PPC OS X が動作することも確認していません。ただし、この使用法は、この配置が特に重要ではないことを示唆しています。(これが機能することを願っています。また、検索者にとっても簡単になることを願っています!)