インテル® IPP 7.0 ライブラリーとのリンクの概要

同カテゴリーの次の記事

インテル® IPP サンプル - エラーの修正

この記事は、インテル® ソフトウェア・ネットワークに掲載されている「Introduction to Linking with the Intel© IPP 7.0 Library」の日本語参考訳です。

ライブラリーをアプリケーションにリンクするには、スタティック・リンクまたはダイナミック・リンクのいずれかを使用できます。スタティック・リンクでは、さらに 2 つのオプションがあり、シングルスレッド・スタティック・ライブラリー、または、マルチスレッド・スタティック・ライブラリーのいずれかにリンクできます。

ダイナミック・リンクとスタティック・リンクのどちらにも長所と短所がありますが、この記事は、リンク方法に関する基本情報を提供するもので、どちらがより優れた方法であるかを説明するものではありません。

以下に説明する手順は、開発システム環境で、インテル® インテグレーテッド・パフォーマンス・プリミティブ (インテル® IPP) ライブラリーを使用するアプリケーションをコンパイルおよびリンクするように設定済みであることを前提としています。各環境の詳しい設定方法については、「インテル® IPP 7.0 ライブラリー:入門ガイド」(英語) を参照してください。このナレッジベース記事は、インテル® IPP ライブラリー 7.0 のバージョンのみを対象としています。

ダイナミック・リンク

ほとんどのインテル® IPP サンプルでは、ダイナミック・リンク (共有オブジェクトとのリンク) がデフォルトで使用されています。インテル® IPP の事前ビルド済みダイナミック・ライブラリーに対してダイナミックにリンクするには、”スタブ・ライブラリー” (Windows* の場合) にリンクするか、直接共有ライブラリー・オブジェクト (Linux* の場合) にリンクする必要があります。この記事で説明するダイナミック・リンクは「暗黙リンク」であり、アプリケーションの実行時にオペレーティング・システムにより自動的にライブラリーが読み込まれます。(「明示的リンク」を使用する場合は、ここで説明する情報についてすでに理解されているでしょうから、この手順は省略してください。)

ダイナミック・ライブラリーに対してリンクすると、実際にアプリケーションに IPP 関数コードを含めなくても、リンカーによりインテル® IPP の外部関数名 (アプリケーション内から呼び出される IPP 関数名など) が検索されます。その場合、呼び出される関数は、アプリケーションの実行ファイルとともに配布されるダイナミック・リンク・ライブラリー (DLL) 内か、共有オブジェクト (SO) ファイル内に存在します。

カスタム共有ライブラリーを (インテル® IPP スタティック・ライブラリーを基に) 作成して配布することも、インテル® IPP ライブラリーに付属する事前ビルド済み共有ライブラリーを配布することも可能です。一般に、カスタム共有ライブラリーでは、アプリケーションが必要とする関数だけを共有ライブラリー・ファイルに含めることができるため、事前ビルド済み共有ライブラリーよりもサイズが小さくなります。

標準の事前ビルド済み共有ライブラリーを配布する場合は、アプリケーションでは使用されない関数が多く含まれることになります。これは、アプリケーションの機能やパフォーマンスには影響しませんが (サイズの大きなダイナミック・ライブラリーのメモリーやページングの要件を無視する場合)、顧客に配布するファイルの数とサイズが大幅に増大します。

次に説明するダイナミック・リンクの設定手順は、アプリケーションとともにデフォルトの事前ビルド済み共有ライブラリー・ファイルを使用することを前提としています。

注: 事前ビルド済みダイナミック・ライブラリーは、インテルの OpenMP* スレッド・ライブラリーを使用してマルチスレッド化されています。アプリケーションまたはランタイム環境が、このスレッド技術に対応していない場合は、シングルスレッドのスタティック・ライブラリーを使用してください。アプリケーションでダイナミック・ライブラリーが必要な場合は、シングルスレッド・スタティック・ライブラリーからカスタムなダイナミック・ライブラリーを作成できます。詳しくは、「インテル® IPP のスレッド化および OpenMP* ライブラリーに関する FAQ」(英語) を参照してください。

Windows* ダイナミック・リンク

インテル® IPP 7.0 では、リンクの依存関係を指定する方法が大幅に簡略化されました。必要な操作は、ipp.h ヘッダーファイルをソースファイルにインクルードし (IPP 関数またはデータ構造を参照するソースファイルにのみ ipp.h ヘッダーファイルをインクルードする必要があります)、その後、どのライブラリー・ファイルをアプリケーションにリンクすべきかを自動的にリンカーに指示する専用のプリプロセッサー・ラベルを定義するだけです。

以下に概要を説明します。

#include “ipp.h”

上記のように、インテル® IPP 関数およびデータ構造を参照するソースファイルに “ipp.h” をインクルードします。

/D_IPP_PARALLEL_DYNAMIC

そして、コンパイラーのコマンドラインで、このオプションを指定します。

上記の方法は、Microsoft* Visual Studio* コンパイラー (Visual Studio* Express コンパイラーも含む) またはインテル® コンパイラーで使用できます。インテル® IPP ヘッダーファイルを参照すると、その仕組みを把握できます。この方法では、それぞれのコンパイラーの “#pragma comment( lib, “libfilename” )” が使用されます。このプラグマの詳細については、http://msdn.microsoft.com/en-us/library/7f0aews7(v=vs.71).aspx (英語) を参照してください。

Linux* ダイナミック・リンク

Linux* プラットフォームでダイナミック・リンクを使用する場合は、上述の Windows* の手順よりも多少複雑な手順が伴います。リンク対象のライブラリーの名前を特定し、リンクリストに含める必要があります。使用する関数のドメインが分かっている場合は、「アプリケーションで必要とされるインテル® インテグレーテッド・パフォーマンス・プリミティブ (インテル® IPP) ライブラリー」(英語) を参照して、必要なライブラリー・ファイルを特定することができます。

ライブラリー (またはドメイン) のリストを作成したら、それぞれの名前に対応するライブラリー・ファイル名を指定し、リストの最後にコア・ライブラリーを含めます。例えば、アプリケーションがオーディオ・コーディング・ドメインおよび信号処理ドメインに属する関数を必要とする場合、 リンクリストは次のようになります。

-lippac –lipps –lippcore

通常、ippcore ライブラリーはリンクリストの末尾に記述します。インテル® IPP サンプル (http://software.intel.com/en-us/articles/intel-integrated-performance-primitives-samples-license-agreement/) とともに配布される makefile には、通常次のように定義されたリストが含まれています。

IPPLIB = -lippac -lipps –lippcore

その後に、makefile 内のマクロ $(IPPLIB) への参照が定義されます。

ドメインで使用しているインテル® IPP ライブラリーを特定するには、インクルード・ファイルで Windows* リンカーに指示するために使用されている #pragma 定義を参照するのが最も簡単な方法です (例えば、画像圧縮ドメイン – ippj.h – は、コア・ライブラリーのほか画像処理および信号処理ドメインも使用しています)。このようなプラグマ文は、Windows* のビルド環境でのみ使用されますが、Linux* のインクルード・ファイルにも含まれています。指定されたドメイン内のすべての関数が、プラグマリストに記載されているほかのドメイン・ライブラリーを使用しているわけではありません。

スタティック・リンク

スタティック・リンクでは、シングルスレッドまたはマルチスレッドのいずれかのスタティック・ライブラリーを選択する必要があります。どちらのライブラリーを選択すべきかは、アプリケーションとランタイム環境の要件によって決定されます。マルチスレッド・スタティック・ライブラリーを選択する場合は、アプリケーションにインテルの OpenMP* ライブラリーも含める必要があります。

スタティック・ライブラリーの方が、ダイナミック・ライブラリーよりも操作は簡単です。インテル® IPP スタティック・ライブラリーに対してリンクすると、関数コードがアプリケーションの実行ファイルの一部として組み込まれます。そのため、アプリケーションの実行ファイルを配布するだけで済みます。マルチスレッド・スタティック・ライブラリーを使用している場合は、必要に応じてインテルの OpenMP* ダイナミック・ライブラリーも含めます。

スタティック・リンクでは、アプリケーション内から呼び出す関数で必要なコードのみが実行ファイルに含まれます。つまり、アプリケーションから 10 種類のインテル® IPP 関数を呼び出す場合には、これら 10 種類の関数 (加えて、これら 10 種類の関数により参照されるその他の関数) のコードのみが最終的な実行ファイルに含まれます。スタティック・リンクの場合、インテル® IPP ライブラリー全体ではなく、アプリケーションに必要な関数のみが含まれます。

マルチスレッド・スタティック・ライブラリーはインテルの OpenMP* ライブラリーを使用するため、このライブラリーへのリンクも必要となります。インテル® IPP スタティック・ライブラリーにリンクする場合でも、インテルの OpenMP* ライブラリーのダイナミック・リンク、スタティック・リンクのどちらでも利用できますが、OpenMP* ダイナミック・ライブラリーにリンクすることを推奨します。インテル® IPP ライブラリーに対してスタティック・リンクを使用する場合も、C ランタイム・ライブラリーなどのほかのシステム・ライブラリーに対してスタティック・リンクを使用する必要はありません。

インテルの OpenMP* ダイナミック・ライブラリーにリンクする場合は、実行ファイルとともにライブラリー・ファイルを配布する必要があります。スタティック・リンクの場合は必要ありませんが、顧客のランタイムシステムにおいて別のアプリケーションで使用される他の OpenMP* ライブラリー (Visual C や GCC との) とのリソース競合が発生する可能性があります。

Windows* スタティック・リンク

上述したように、インテル® IPP 7.0 リリースでは、Windows* システムでのリンクの依存関係の指定方法が大幅に簡略化されました。必要な操作は、ipp.h ヘッダーファイルをソースファイルにインクルードし、アプリケーションに対してリンクするスタティック・ライブラリー・オプションを指定するプリプロセッサー・ラベルを定義するだけです。

以下に概要を説明します。

#include “ipp.h”

このように、インテル® IPP 関数およびデータ構造を参照するソースファイルに “ipp.h” をインクルードします。

/D_IPP_PARALLEL_STATIC

または

/D_IPP_SEQUENTIAL_STATIC

そして、コンパイラーのコマンドラインで、上記のいずれかのオプションを指定します。

上記の方法は、Microsoft* Visual Studio* コンパイラー (Visual Studio* Express コンパイラーも含む) またはインテル® コンパイラーで使用できます。インテル® IPP ヘッダーファイルを参照すると、その仕組みを把握できます。この方法では、それぞれのコンパイラーの “#pragma comment( lib, “libfilename” )” 機能が使用されます。このプラグマの詳細については、http://msdn.microsoft.com/en-us/library/7f0aews7(v=vs.71).aspx (英語) を参照してください。

“_IPP_PARALLEL_STATIC” というプリプロセッサー・ラベルは、マルチスレッド・スタティック・ライブラリーを使用することを示しています。また、”_IPP_SEQUENTIAL_STATIC” というプリプロセッサー・ラベルは、シングルスレッド・スタティック・ライブラリーを使用することを示しています。

Linux* スタティック・リンク

Linux* プラットフォームでスタティック・リンクを使用するには、上記の Windows* の手順よりも多少複雑な手順を伴いますが、Linux* のダイナミック・リンク方法よりも簡単です。Linux* のダイナミック・リンク・プロセスとは異なり、事前にリンク対象のライブラリー名を特定し、リンクリストに追加する必要はありません。代わりに、インテル® IPP スタティック・ライブラリーをすべてリンクリストに列挙するだけで、リンカーにより自動的に処理されます。

マルチスレッド・ライブラリーを使用する場合は、makefile 内のリンクリストのマクロ定義は次のようになります。

IPPLIB = -lippac_t -lippdc_t -lippcc_t -lippcv_t -lippj_t -lippdi_t -lippch_t -lippm_t -lippr_t -lippsc_t -lippvm_t -lippvc_t -lippi_t -lipps_t -lippcore_t -liomp5 -lpthread

シングルスレッド・ライブラリーを使用する場合は、makefile 内のリンクリストのマクロ定義は次のようになります。

IPPLIB = -lippac_l -lippdc_l -lippcc_l -lippcv_l -lippj_l -lippdi_l -lippch_l -lippm_l -lippr_l -lippsc_l -lippvm_l -lippvc_l -lippi_l -lipps_l -lippcore_l

標準的な Linux* リンカーはデフォルトでシングルパスを使用するため、ippcore ライブラリーは常にインテル® IPP ライブラリー・ファイルのリンクリストの末尾に配置します。上記のリストは、ライブラリー間の相互依存関係を解決します。

ただし、ライブラリー間の相互依存のためにリンクエラーが生じる場合は、-( および –) オプション (または同等の –start-group および –end-group オプション) でリンク対象のライブラリー・リストを囲み、リンカーにマルチパス動作を強制する必要があります。その場合、リンカーのパフォーマンスが多少低下します。あるいは、-( および -) オプションを使用する代わりに、主要なライブラリー・ファイルに依存するライブラリー・ファイルまたはオブジェクト・コード・ファイルの後に、ライブラリー・ファイルをもう一度リストしてライブラリー名を繰り返すことで、循環依存を解決することもできます。nm コマンドや ldd コマンドを使用して、外部参照と依存関係を特定することも可能です。

参考情報

インテル® IPP マルチスレッド・スタティック・ライブラリーの使用 (英語)
インテル® IPP を使用した Windows* アプリケーションのビルド (英語)
Microsoft* Visual C++* とインテル® C++ コンパイラーを使用したコンパイルとリンク (英語)
エラー LNK2001: 未解決の外部シンボル _ipp* (英語)
インテル® IPP アプリケーションのビルド方法 (英語)
インテル® IPP – インテル® IPP リンクモデル – クイック・リファレンス・ガイド (英語)
インテル® IPP- ドメイン別のライブラリー依存関係 (英語)
インテル® IPP – スレッド化/OpenMP* に関する FAQ (英語)

関連記事

  • 新しい最適化レポートを使用してインテル® コンパイラーをさらに活用する新しい最適化レポートを使用してインテル® コンパイラーをさらに活用する この記事は、インテル® デベロッパー・ゾーンに公開されている「Getting the Most out of your Intel® Compiler with the New Optimization […]
  • null ポインターの逆参照が引き起こす未定義の動作null ポインターの逆参照が引き起こす未定義の動作 この記事は、インテル® デベロッパー・ゾーンに公開されている「Null Pointer Dereferencing Causes Undefined Behavior」の日本語参考訳です。 この記事の PDF 版はこちらからご利用になれます。 私は最近、C/C++ で P が null ポインターの場合に […]
  • インテル® AES New Instructions (インテル® AES-NI)インテル® AES New Instructions (インテル® AES-NI) この記事は、インテル® デベロッパー・ゾーンに掲載されている「Intel® Advanced Encryption Standard Instructions (AES-NI)」の日本語参考訳です。 はじめに AES (Advanced Encryption Standard) は、2011 […]
  • インテル® VTune™ Amplifier XE 2015 の新機能インテル® VTune™ Amplifier XE 2015 の新機能 この記事は、インテル® デベロッパー・ゾーンに掲載されている「What's new? - Intel® VTune™ Amplifier XE 2015」の日本語参考訳です。 インテル® VTune™ Amplifier XE […]
  • Parallel Universe マガジンParallel Universe マガジン Parallel Universe へようこそ。 米国インテル社が四半期に一度オンラインで公開しているオンラインマガジンです。インテルの技術者によるテクノロジーの解説や、最新ツールの紹介など、並列化に関する記事を毎号掲載しています。第1号からのバックナンバーを PDF 形式で用意しました、ぜひご覧ください。 12 […]