2

Solaris 11 で Sun Studio 12.4 および 12.5 を使用しています。CRC32 のストレート C/C++ 実装、または Intel 組み込み関数を使用した CRC32 の最適化バージョンを提供するソース ファイルがあります。実行時に、関数ポインターに適切な実装が設定されます。

デュアル Xeon を使用した x86 サーバーでのテストでは、コンパイラのバージョンに基づいてコード パスを利用できるようにしているため、次の結果が生成されます。SunCC 12.1 は SSE4 のサポートを追加したため (マトリックスを適切に解析した場合) __SUNPRO_CC >= 0x5100、.

"crc.cpp", line 311: ube: error: _mm_crc32_u8 intrinsic requires at least -xarch=sse4_2.

SunCC は、やなどの通常の GCC 定義を定義していませ。さらに、SunCC は、コンパイラのバージョンがサポートを示す MS VC++ のように、組み込み関数を利用可能にしていないようです。__SSE4_1____SSE4_2__

SunCC はオプションに基づいて機能を有効にしているように見え-xarchますが、プリプロセッサでそれを検出する方法が明確ではありません。さらに、使用-xarchすると、下位レベルのプロセッサ (「最小」プラットフォームのようなもの) でプログラムの実行が失敗する原因となるビットが設定されます。

2 つの質問があります。

  • -xarchプリプロセッサでオプションを検出するにはどうすればよいですか?
  • -xarchプログラムが下位レベルのプロセッサで実行できるように、ビットを無効にするにはどうすればよいですか?

以下は、 でコンパイルしたマクロ ダンプからのもの-xarch=aesです。利用可能な機能を示すものは何もないことに注意してください。

$ /opt/solarisstudio12.4/bin/CC -native -m64 -xarch=aes -xdumpmacros -E /dev/null 2>&1 | /usr/gnu/bin/sort --ignore-case

#1 "/dev/null"
#define __alignof__ __alignof
#define __amd64 1
#define __amd64__ 1
#define __ARRAYNEW 1
#define __asm asm
#define __asm__ asm
#define __attribute __attribute__
#define __builtin_constant_p __oracle_builtin_constant_p
#define __builtin_fpclassify __oracle_builtin_fpclassify
#define __builtin_huge_val __oracle_builtin_huge_val
#define __builtin_huge_valf __oracle_builtin_huge_valf
#define __builtin_huge_vall __oracle_builtin_huge_vall
#define __builtin_infinity __oracle_builtin_infinity
#define __builtin_isfinite __oracle_builtin_isfinite
#define __builtin_isgreater __oracle_builtin_isgreater
#define __builtin_isgreaterequal __oracle_builtin_isgreaterequal
#define __builtin_isinf __oracle_builtin_isinf
#define __builtin_isless __oracle_builtin_isless
#define __builtin_islessequal __oracle_builtin_islessequal
#define __builtin_islessgreater __oracle_builtin_islessgreater
#define __builtin_isnan __oracle_builtin_isnan
#define __builtin_isnormal __oracle_builtin_isnormal
#define __builtin_isunordered __oracle_builtin_isunordered
#define __builtin_nan __oracle_builtin_nan
#define __builtin_signbit __oracle_builtin_signbit
#define __BUILTIN_VA_STRUCT 1
#define __cplusplus 199711L
#define __DATE__ "Jul 11 2016"
#define __FILE__ 
#define __has_attribute(x) __oracle_has_attribute(x)
#define __has_nothrow_assign(x) __oracle_has_nothrow_assign(x)
#define __has_nothrow_constructor(x) __oracle_has_nothrow_constructor(x)
#define __has_nothrow_copy(x) __oracle_has_nothrow_copy(x)
#define __has_trivial_assign(x) __oracle_has_trivial_assign(x)
#define __has_trivial_constructor(x) __oracle_has_trivial_constructor(x)
#define __has_trivial_copy(x) __oracle_has_trivial_copy(x)
#define __has_trivial_destructor(x) __oracle_has_trivial_destructor(x)
#define __has_virtual_destructor(x) __oracle_has_virtual_destructor(x)
#define __is_abstract(x) __oracle_is_abstract(x)
#define __is_base_of(x,y) __oracle_is_base_of(x,y)
#define __is_class(x) __oracle_is_class(x)
#define __is_empty(x) __oracle_is_empty(x)
#define __is_enum(x) __oracle_is_enum(x)
#define __is_final(x) __oracle_is_final(x)
#define __is_literal_type(x) __oracle_is_literal_type(x)
#define __is_pod(x) __oracle_is_pod(x)
#define __is_polymorphic(x) __oracle_is_polymorphic(x)
#define __is_standard_layout(x) __oracle_is_standard_layout(x)
#define __is_trivial(x) __oracle_is_trivial(x)
#define __is_union(x) __oracle_is_union(x)
#define __LINE__ 
#define __LP64__ 1
#define __PRAGMA_REDEFINE_EXTNAME 1
#define __STDC__ 0
#define __sun 1
#define __SUN_PREFETCH 1
#define __SunOS 1
#define __SunOS_5_11 1
#define __SUNPRO_CC 0x5130
#define __SUNPRO_CC_COMPAT 5
#define __SVR4 1
#define __TIME__ "20:58:00"
#define __underlying_type(x) __oracle_underlying_type(x)
#define __unix 1
#define __volatile volatile
#define __volatile__ volatile
#define __x86_64 1
#define __x86_64__ 1
#define _BOOL 1
#define _LARGEFILE64_SOURCE 1
#define _LP64 1
#define _SIGNEDCHAR_ 1
#define _TEMPLATE_NO_EXTDEF 1
#define _WCHAR_T 
#define sun 1
#define unix 1
4

3 に答える 3

2

あなたの特定の状況 (その 2 番目の部分) に対して、あなたが望むことを行うための唯一の簡単な方法は、明示的に "-xarch=sse4.2" を設定してコンパイルすることだと思います (これにより、コンパイラーは SSE4.2 組み込み関数を展開できます)。次に、HWCAP ビットを最小限のアーキテクチャに落とします (これにより、SSE4.2 より前のハードウェアでプログラムを実行できるようになります)。

HWCAP の削除については、 https ://docs.oracle.com/cd/E23823_01/html/816-5165/elfedit-1.html を参照してください。

(例 2 ハードウェア機能ビットの削除)

于 2016-07-13T13:46:42.423 に答える
1

まず、コンパイル済みバイナリから命令セット フラグを削除したくありません。オプションを指定してコンパイル-xarch=NNNNすると、コンパイルはそれらの命令を使用します。引数で指定したアーキテクチャの命令を実装していない「下位の」プロセッサで実行しようとすると-xarch、バイナリが機能しない可能性が高くなります。

Solaris Studio 12.4: C User's Guideから:

1.3 バイナリ互換性の検証

Solaris システムでは、Solaris Studio 11 以降、Oracle Solaris Studio コンパイラでコンパイルされたプログラムバイナリは、コンパイルされたバイナリによって想定される命令セットを示すアーキテクチャハードウェアフラグでマークされます。実行時に、これらのマーカー フラグがチェックされ、実行しようとしているハードウェア上でバイナリを実行できることが確認されます。

これらのアーキテクチャ ハードウェア フラグを含まないプログラムを、適切な機能または命令セットの拡張機能が有効になっていないプラットフォームで実行すると、明示的な警告メッセージが表示されることなく、セグメンテーション フォールトまたは誤った結果が発生する可能性があります。

また、機能と命令セットについての言及にも注意してください。Solaris のドキュメントに関する私の経験では、その 1 つを脇に置くだけで十分な警告が得られます。

プリプロセッサを介して利用可能な命令セットを検出する方法がわかりません。Solaris Studio の Oracle フォーラム ( https://community.oracle.com/community/server_%26_storage_systems/application_development_in_c__c%2B%2B__and_fortran/developer_studio_c_c%2B%2B_fortran_compilers ) でヘルプが得られる場合があります。

そこでも、プリプロセッサを使用する方法が見つからないのではないかと思います。Solaris でプラットフォームおよび命令セット固有の実装を提供する通常の方法は、特定の共有オブジェクトを使用することです。Solaris Linker and Libraries Guideから:

命令セット固有の共有オブジェクト

動的トークン$ISALISTは実行時に展開され、ユーティリティによって表示されるように、このプラットフォームで実行可能なネイティブ命令セットを反映しますisalist(1)

トークンを組み込んだ文字列名$ISALISTは、効果的に複数の文字列に複製されます。各ストリングには、使用可能な命令セットの 1 つが割り当てられます。このトークンは、フィルターまたは実行パスの指定でのみ使用できます 。

...

または、同様の依存関係を持つアプリケーションがMMX構成済みで実行されますPentium Pro

$ ldd -ls prog
.....
  find object=libbar.so.1; required by ./libfoo.so.1
    search path=/opt/ISV/lib/$ISALIST  (RPATH from file ./libfoo.so.1)
      trying path=/opt/ISV/lib/pentium_pro+mmx/libbar.so.1
      trying path=/opt/ISV/lib/pentium_pro/libbar.so.1
      trying path=/opt/ISV/lib/pentium+mmx/libbar.so.1
      trying path=/opt/ISV/lib/pentium/libbar.so.1
      trying path=/opt/ISV/lib/i486/libbar.so.1
      trying path=/opt/ISV/lib/i386/libbar.so.1
      trying path=/opt/ISV/lib/i86/libbar.so.1

ライブラリ検索が「最上位」の命令セット固有のライブラリから開始され、「下位」のライブラリに移動する方法に注意してください。これにより、「最速の固有」から「最も遅い汎用」まで、複数の命令セット固有の共有オブジェクトを配置できます。 libc.soSolaris では、 などのライブラリ関数のプラットフォーム固有のバージョンを提供するためにこれを行いますmemcpy()

于 2016-07-12T11:12:16.333 に答える