18


4

http://www.threadingbuildingblocks.org/[intelのTBBライブラリ]を自分のアプリケーションに静的にリンクする方法を教えてください。 スケジューラの不公平な負荷分散など、 http://www.threadingbuildingblocks.org/wiki/index.php?title=Using_TBB[警告]を知っていますが、スケジューラは必要ありません。コンテナだけが必要です。 OK。

とにかく私はこれが文書化されていないが、行うことができることを知っています、しかし私はちょうど今それをする方法を見つけることができないようです(私はどこか前にそれを見たが)。

それで誰かが何か手がかりを知っているか、持っていますか?

ありがとう

7 Answer


11


これは強くお勧めできません。

_ _ 静的にリンクされたライブラリを提供するTBBのバージョンはありますか?

以下の理由により、TBBは静的にリンクされたライブラリとしては提供されていません。

ほとんどのライブラリはローカルで動作します。 例えば、インテル(R)MKL FFTは配列を変換します。 FFTのコピーがいくつあるかは無関係です。 複数のコピーとバージョンが問題なく共存できます。 しかし、ライブラリの中には、メモリやプロセッサなどのプログラム全体のリソースを制御するものがあります。 たとえば、ガベージコレクタはプログラム全体のメモリ割り当てを制御します。 同様に、TBBはプログラム全体のタスクのスケジューリングを制御します。 効果的に仕事をするためには、これらのそれぞれがシングルトンでなければなりません。つまり、プログラム全体の活動を調整できる唯一のインスタンスを持ちます。 1つのプログラムでTBBスケジューラのインスタンスをk個許可すると、ソフトウェアスレッドはハードウェアスレッドのk倍になります。 マシンがk倍にオーバーサブスクライブされ、コンテキストの切り替え、キャッシュの競合、およびメモリの消費が増えるため、プログラムの効率が悪くなります。 さらに、ネストされた並列処理に対するTBBの効率的なサポートは、ネストされた並列処理が異なるスケジューラのネストされた呼び出しから発生した場合には無効になります。

プログラム全体のシングルトンを作成するための最も実用的な解決策は、シングルトンを含む動的共有ライブラリです。 もちろん、スケジューラが協力できれば、シングルトンは必要ありません。 しかし、その協力には中央エージェントがコミュニケーションをとることが必要です。つまり、シングルトンです。

静的にリンク可能なバージョンのTBBを省略するという私たちの決定は、私たちのOpenMPの経験に強く影響されました。 TBBと同様に、OpenMPもプログラム全体でスケジュールを試みます。 OpenMPランタイムの静的バージョンはかつて提供されていました、そしてそれは重複したスケジューラから生じる問題の恒常的な原因でした。 その歴史を繰り返さないのが一番だと思います。 これらの考慮事項の妥当性の間接的な証明として、Microsoft Visual Cが動的ライブラリを介したOpenMPサポートのみを提供するという事実を指摘できます。 _ _

ソース:http://www.threadingbuildingblocks.org/faq/11#sthash.t3BrizFQ.dpuf


8


編集-`+ extra inc`を使用するように変更されました。 ありがとうジェフ!

次のパラメータで構築してください。

make extra_inc=big_iron.inc

静的ライブラリが構築されます。 `+ build / big iron.inc`の警告を参照してください。


4


ソースから静的ライブラリを構築する

+ make extra inc = big iron.inc

追加のオプションが必要な場合は、代わりに次のように構築してください。

+ make extra inc = big_iron.inc +

ノードごとに複数のTBBプログラムを実行する

マルチプロセッシングアプリケーションを実行すると MPIを使用している場合は、オーバーサブスクリプションを回避するために、適切な数のスレッドでTBBスケジューラを明示的に初期化する必要があります。

大規模なアプリケーションでのこの例はhttps://github.com/m-a-d-n-e-s-s/madness/blob/master/src/madness/world/thread.ccにあります。

ドキュメントへのコメント

この機能は長年(少なくとも2013年以降)使用されていますが、他の回答で説明されている理由で文書化されていません。

歴史ノート

この機能は、ローカルでマウントされたファイルシステムがないために、IBM Blue GeneおよびCrayスーパーコンピューターが共有ライブラリーをサポートしていないか、またはそれらを使用してもうまく機能しなかったために開発されました。


2


オープンソース版を使う:

"make tbb"を実行した後、build / linux_xxxxxxxx_releaseフォルダに移動します。

次に実行します。

ar  -  r libtbb.a concurrent_hash_map.o o tbb_misc_ex.o mutex.o recursive_mutex.o condition_variable.o concurrent_monitor.o private_server.o rml_tbb.o task_group_context.o governor.o market.o arena.o scheduler.o observer_proxy.obb.o tb.thub.biz.html .o concurrent_vector_v2.o concurrent_queue_v2.o spin_rw_mutex_v2.o task_v2.o

そして、あなたはlibtbb.aを出力として得なければなりません。

あなたのプログラムは "-ldl"とlibtbb.aの両方でビルドするべきであることに注意してください。


2


TBBチームによって公式に承認されているわけではありませんが、 `+ make extra_inc = big_iron.inc +`を使用して、独自に静的にリンクされたTBBのバージョンを構築することができます。

私はWindowsやMacOSではテストしていませんが、Linuxではうまくいきました(https://github.com/philipp-classen/tbb-static-linking-tutorial/blob/master/Dockerfile#L13[source])。

wget https://github.com/01org/tbb/archive/2017_U6.tar.gz
tar xzfv 2017_U6.tar.gz
cd tbb-2017_U6
make extra_inc=big_iron.inc

生成されたファイルは `+ tbb-2017_U6 / build / linux * release +`にあります。

アプリケーションを静的TBBバージョンにリンクすると、

  • `+ -static +`スイッチを使用してg ++を呼び出す

  • tbb( + -ltbb +)およびpthread( + -lpthread +)に対するリンク

私のテストでは、手動でビルドしたTBBバージョンからすべての `+ .o `ファイルを明示的に参照する必要もありました。 プロジェクトによっては、 ` -pthread +`をgccに渡す必要がある場合もあります。

このGithubレポジトリのすべてのステップを文書化するためのおもちゃの例を作成しました。

生成されたバイナリが他のLinuxディストリビューションに移植可能であることを確認するためのテストコードも含まれています。


1


残念ながらそれは可能ではないようです: TBBサイトから。 あなたが本当に静的リンケージを必要とするなら、Intelフォーラムでの1つの提案はそれを手動でコンパイルすることでした: Intelからフォーラム


-1


ファイルをリンクするだけで、私はそれを行って動作します。 これがSConscriptファイルです。 tbbとtbbmallocで同じ名前を持つシンボルが重複して定義されないようにすることと、両方のライブラリで同じ名前を持つ別のシンボルが作成されることを防ぐためにITT_NOTIFYを使用することを防ぎました。

インポート( 'g_CONFIGURATION')インポートosインポートSCutilsインポートユーティリティ

tbb_basedir = os.path.join(g_CONFIGURATION ['basedir']、 'サードパーティ/ tbb40_233oss /')

#print 'TBB base:'、tbb_basedir #print 'CWD:'、os.getcwd()

ccflags = [] cxxflags = [' -  m64'、 ' -  march = native'、 ' -  I {0}'、フォーマット(tbb_basedir)、 ' -  I {0}'、フォーマット(os.path.join(tbb_basedir、) 'src'))、# ' -  I {0}'。フォーマット(os.path.join(tbb_basedir、 'src / tbb'))、 ' -  I {0}'。フォーマット(os.path.join(tbb_basedir) 、 'src / rml / include'))、 '-I {0}'。format(os.path.join(tbb_basedir、 'include'))、] cppdefines = [# 'DO_ITT_NOTIFY'、 'USE_PTHREAD'、 '__TBB_BUILD = 1 '、] linkflags = []

g_CONFIGURATION ['build'] == 'debug'の場合:ccflags.extend(['-O0'、 '-g'、 '-ggdb2'、])cppdefines.extend(['TBB_USE_DEBUG'、])

それ以外の場合:ccflags.extend(['-O2'、])

tbbenv =環境(プラットフォーム= 'posix'、CCFLAGS = ccflags、CXXFLAGS = cxxflags、CPPDEFINES = cppdefines、LINKFLAGS = linkflags)

################################################## ###########################SCutils.has_option( 'verbose')でなければ冗長性を構築します:SCutils.setup_quiet_build(tbbenv、SCutilsならTrue)。 has_option( 'colorblind')それ以外の場合はFalse)######################################### ###################################


tbbmallocenv = tbbenv.Clone()

tbbmallocenv.Append(CCFLAGS = [' -  fno-rtti'、 ' -  fno-exceptions'、 ' -  fno-schedule-insns2'、])

#tbbenv.Command( 'version_string.tmp'、None、 '')

#open(os.path.join(os.getcwd()、 'version_string.tmp')、 'wb')を使用して、version_string.tmpをfdとして記述します。(out、err、ret)= utils.xcall(['/ bin / bash '、os.path.join(g_CONFIGURATION [' basedir ']、'サードパーティ/ tbb40_233oss / build / version_info_linux.sh ')]))

ret:SCons.Errors.StopErrorを発生させます( 'version_info_linux.shの実行に失敗しました')

fd.write(out); #print 'version_stringを入れる'、os.path.join(os.getcwd()、 'version_string.tmp')#print out fd.close()

結果= []

def setup_tbb():print 'CWD:'、os.getcwd()tbb_sources = SCutils.find_files(os.path.join(tbb_basedir、 'src / tbb')、r '^。* \。cpp $')tbb_sources。 (['src / tbbmalloc / frontend.cpp'、 'src / tbbmalloc / backref.cpp'、 'src / tbbmalloc / tbbmalloc.cpp'、 'src / tbbmalloc / large_objects.cpp'、 'src / tbbmalloc / backend。 cpp '、' src / rml / client / rml_tbb.cpp '、])

print tbb_sources result.append(tbbenv.StaticLibrary(target = 'libtbb'、source = tbb_sources))

setup_tbb()

戻る( '結果')