2014年4月23日 星期三

GCC 4.9 Release Note

以下是 4.9 更新的部份, 主要整理自官方 Release 頁面, 但由於個人能力有限, target 相關僅翻譯 x86, arm, aarch64 以及 nds32, 語言相關方面則只翻譯 C/C++ 部份:

提醒!

  • 移除 mudflap run time checker, mudflap 相關的選項還會留著但不會有任何作用.
  • 許多老舊系統以及年久沒維護或測試的 target 在 GCC 4.9 將會被宣佈為過時的 (obsolete), 除非有善心人士幫忙不然在下個 Release 的時候就會直接砍掉.

    下列的系統將將被列為 obsoleted:
    • Solaris 9 (*-*-solaris2.9). 詳情請洽公告
  • 更多 Porting 到 GCC 4.9 的相關資訊請洽 porting guide.

一般性的最佳化改善

  • AddressSanitizer, 快速記憶體錯誤偵測器, 在 ARM 上面可以動了!!
  • UndefinedBehaviorSanitizer (ubsan), 快速未定義行為偵測器, 可以透過 -fsanitize=undefined 這個 flag 開啟. 許多計算(computations) 都會被塞入(instrumented)偵測未定義行為的東西, 目前這個東東可以在 C/C++ 上運作.

連結時期最佳化(Link-time optimization LTO)的改善:

  • 型態合併的部份砍掉重練. 新的實作更快更好更省記憶體!
  • 更好的切割演算法, 連結時期使用更少的 streaming.
  • 透過即早砍掉 Vritual Method 來減少 Object File Size, 以及改善連結時間跟編譯時間.
  • 函數內容 (Function bodies) 需要時才載入 (loaded on-demand), 以及即早釋放來改善連結時期所消耗的記憶體.
  • C++ 隱藏(hidden) 函數們現在可以被最佳化掉.
  • 當使用 linker plugin 時, 開 -flto 會產生只放 GCC IR 的苗條 (slim) Object File (.o), 使用 -ffat-lto-objects 的時候才會產生肥大 (Fat) Object File, 裡面就會裝 IR 以及 machine code. 要產生可以餵給 LTO 的 static library 時, 請使用 gcc-ar 以及 gcc-ranlib; 要看 symbol 時則請用 gcc-nm. (需要 ar, ranlib 以及 nm 有開啟 plugin 支援).
  • 以 LTO build FireFox 為例, 記憶體使用量從 15G 變 3.5G, 連結時間由 1700 秒變 350 秒.

跨函數最佳化(Inter-procedural optimization) 的改善:

  • 新的型別繼承分析模組使得 devirtualization 有所改善!
  • Devirtualization 現在會把匿名命名空間以及 C++11 的 final 關鍵字一併考慮進去分析.
  • 新的 speculative devirtualization pass (可透過 -fdevirtualize-speculatively 開啟).
  • Function Call 被 speculation 後若太貴的話也可能會變回 indierct call.
  • Local aliases are introduced for symbols that are known to be semantically equivalent across shared libraries improving dynamic linking times. 引入 Local Alias, 讓 gcc 可以判斷 symbol 穿越過 shared librrary 後是否還是否語意等價 (譯註:沒理解錯的話應該是指 Escape analysis XD).

回饋導向最佳化(Feedback directed optimization) 的改善:

  • C++ inline function 的 Profiling 資訊現在變得更可靠.
  • 新的 time profiling 會吐一個 Function 執行時間的排序.
  • 新的 Function Reorder pass (可透過 -freorder-functions 開啟) 可以大幅的減少大型應用程式的起始時間, 這項功能目前只對於 LTO 有效, 非 LTO 須等到 binutils 全面支援,
  • 即日起開啟 LTO 即可享有回饋導向的 Inderct Call 移除以及跨模組的 devirtualization.

新語言以及語言相關的改善:

  • gcc/g++ 現在支援 OpenMP 4.0, 加入新的編譯選項 -fopenmp-simd 來開啟 OpenMP 的 SIMD directive. 另外也加入了新的選項 -fsimd-cost-model= 來選擇迴圈中的 annotatation 以及 Cilk Plus simd directive 來作為向量化的 Cost Model; 若只有下 -Wopenmp-simd 則會提醒使用者 Cost Model 被 simd directive 給覆蓋.
  • 新的警告選項 -Wdate-time, 主要針對 C, C++ 以及 Fortan Compiler, 這個選項開啟時, 若使用到 __DATE__, __TIME__ 或 __TIMESTAMP__ Marco 則會發出警告, 提醒使用者會無法生出完全一模一樣 (bit-wise-identical) 的編譯結果.

C 家族

  • GCC 現在支援多采多姿的診斷訊息, -fdiagnostics-color=auto 時會會自動偵測是否書出到終端機, 是的話就會多采多姿. -fdiagnostics-color=always 則會強迫多采多姿輸出, 另外 GCC_COLORS 這個環境變數也可以客製化顏色或關閉多采多姿輸出, 如果 GCC_COLORS 有設定的話, 會採用 -fdiagnostics-color=auto 為預設值, 否則預設值是 -fdiagnostics-color=never. 範例診斷訊息輸出
        $ g++ -fdiagnostics-color=always -S -Wall test.C
        test.C: In function ‘int foo()’:
        test.C:1:14: warning: no return statement in function returning non-void [-Wreturn-type]
         int foo () { }
                      ^
        test.C:2:46: error: template instantiation depth exceeds maximum of 900 (use -ftemplate-depth= to increase the maximum) instantiating ‘struct X<100>’
         template <int N> struct X { static const int value = X<N-1>::value; }; template struct X<1000>;
                                                      ^
        test.C:2:46:   recursively required from ‘const int X<999>::valuetest.C:2:46:   required from ‘const int X<1000>::valuetest.C:2:88:   required from here
    
        test.C:2:46: error: incomplete type ‘X<100>’ used in nested name specifier
        
  • 增加新的 pragma: #pragma GCC ivdep, 讓使用者告訴 GCC 迭代間無相依性, 來避免產生過度保守的 SIMD 指令.
  • 支援 Cilk Plus 可透過 -fcilkplus 來使用, Cilk Plus 是一組 C/C++ 語言的語言延伸(extension) 讓其支援資料層級或任務層級的平行化, 目前的實作是遵照 ABI 1.2 版, 除了 _Cilk_for 外已經全數實作完成.

C

  • 支援 ISO C11 的 Atomic (_Atomic type specifier, qualifier 以及 stdatomic.h).
  • 支援 C11 _Generice 關鍵字.
  • 支援 C11 thread-local storage (_Thread_local, 類似 GNU C 中的 __thread)
  • 幾乎完全支援 C11, 完成度大概就跟 C99 的支援度差不多:
    修正一堆 bug 以及新增 C11 相關的關鍵字 (除了一些 Corner Case 外幾乎全部支援, 可透過 fextended-identifiers 開啟), 浮點數相關運算 (大部分但不是完整的 C99 功能, 可參考 C99 的附錄 F 及 G) 以及一些選擇性功能 Annexes K (Bounds-checking interface) 以及 L (Analyzability).
  • 增加新的 C extension: __auto_type, 可提供部份類似 C++11 中 auto 的功能.

C++

  • 目前 G++ 實作 C++1y 中的 return type deduction 已經更新到 N3638, 這個提案目前已經被接受到 working paper 中. Most notably, 可透過 decltype(auto) 來取得 decltype semantics 的回傳型別, 相較之下一般的 auto 則是取得 template argument deduction semantics.
    int& f();
             auto  i1 = f(); // int
    decltype(auto) i2 = f(); // int&
    
  • G++ 支援 C++1y 的 lambda capture initializers:
    [x = 42]{ ... };
    
    事實上他已經在 GCC 4.5 中被支援了, 使用 -std=c++1y 的話 compiler 就不會抱怨, 目前支援 parenthesized 初始化以及 brace-enclosed 初始化的形式.
  • G++ 支援 C++1y 的可變長度陣列 (VLA: variable length arrays), 事實上 G++ 支援 GNU/C99-style VLA 很久了~但現在支援了 initializers 以及 lambda capture by reference. 在 C++1y 模式下 G++ 會抱怨某些 VLA 還沒被正式收錄(permitted) 到 Draft Standard 中的功能, 例如指向 VLA 的 type 或著是對 VLA 使用 sizeof operator. 這部份的功能不會出現在 C++14 中, 但有可能出現在更未來的 C++17 中.
    void f(int n) {
      int a[n] = { 1, 2, 3 }; // throws std::bad_array_length if n < 3
      [&a]{ for (int i : a) { cout << i << endl; } }();
      &a; // error, taking address of VLA
    }
    
  • G++ 支援 C++1y 中的 [[deprecated]] 屬性, 就像 [[gnu::deprecated]] 屬性一樣, 類別或函數都可以套用:
    class A;
    int bar(int n);
    #if __cplusplus > 201103
    class [[deprecated("A is deprecated in C++14; Use B instead")]] A;
    [[deprecated("bar is unsafe; use foo() instead")]]
    int bar(int n);
    
    int foo(int n);
    class B;
    #endif
    A aa; // warning: 'A' is deprecated : A is deprecated in C++14; Use B instead
    int j = bar(2); // warning: 'int bar(int)' is deprecated : bar is unsafe; use foo() instead
    
  • G++ 支援 C++1y 中的 digit separators. 長的數字常數可被 ' 來切開表示藉此提升可讀性:
    int i = 1048576;
    int j = 1'048'576;
    int k = 0x10'0000;
    int m = 0'004'000'000;
    int n = 0b0001'0000'0000'0000'0000'0000;
    
    double x = 1.602'176'565e-19;
    double y = 1.602'176'565e-1'9;
    
  • G++ 支援 C++1y polymorphic(多型) lambda
    // a functional object that will increment any type
    auto incr = [](auto x) { return x++; };
    

Runtime Library (libstdc++)

  • 改善 C++11 的支援, 其中包含:
    • 支援 <regex>
    • <map>, <set>, <unordered_map> 以及 <unordered_set> 現在都符合 allocator-aware 的需求了!
  • 改善許多實驗性的 C++14 支援, 包含:
    • 沒有 const 的 constexpr 成員函數.
    • 實作 std::exchange()
    • 支援透過型別取值的 tuple
    • 實作 std::make_unique
    • 實作 std::shared_lock
    • 讓 std::result_of SFINAE-friendly;
    • integral_constant 新增 operator()
    • 新增標準函式庫中的使用者字定義字面常數 (user-defined literals), 例如 std::basic_string, std::chrono::duration, 以及 std::complex
    • 為 std::equal 及 std::mismatch 新增 non-modifying sequence oprations 的版本 oprations
    • 新增針對 quoted strings 的 IO manipulators.
    • 新增 constexpr member 到 <utility>, <complex>, <chrono> 以及部份容器.
    • 新增編譯時期的 std::integer_sequence
    • 新增 cleaner transformation traits
    • 讓 <functional> 中的 operator functors 更好用而且更一般化 (more generic).
    • 實作 std::experimental::optional.
    • 實作 std::experimental::string_view.
    • std::copy_exception 這個非標準的函數被 deprecate , 在未來會移除, 請換使用 std::make_exception_ptr.

新的 Target 以及 Target 相關改善:

AArch64

  • 新增 ARMv8-A 加密以及 CRC 的 intrinsic, 目前要透過 -march=armv8-a+crc 以及 -march=armv8-a+crypto 來開啟.
  • 初步支援 ILP32, 目前可透過 -mabi=ilp32 來開啟, ILP32 目前是個實驗性質的 ABI, 尚在 beta 階段.
  • 涵蓋更多的 ISA: 現在包含 SIMD extensions 以及相關的 intrinsic.
  • AArch64 目前預設使用 Local Register Allocator (LRA)!
  • 在 AArch64 中 REE (Redundant extension elimination) Pass 預設開啟.
  • 改善 Cortex-A53 以及 Cortex-A57 的微調(Tuning).
  • 初步 big.LITTLE 微調可整合 Cortex-A57 以及 Cortex-A53, 可透過 -mcpu=cortex-a57.cortex-a53 來開啟.
  • 大量的基礎建設改善使得 ARM 以及 AArch64 的 Code Gen 獲得不思議的改善.

ARM

  • 目前不再預設 Advanced SIMD (Neon) 來操作 64-bit scalar, 這部份已經被證實只能改善小幅度的 case, 可透過 -mneon-for-64bits 來開啟.
  • 更多的 ARMv8-A architecture 支援, 目前 Thumb32 指令的嚴格限制版的 IT block 可透過 -mrestrict-it 來開啟, 並且搭配 -march=armv7-a 或 -march=armv7ve 來產生對 ARMv8-A deprecated instructions 更佳的相容性.
  • 支援一些 ARMv7ve 相關的架構, 可透過 -march=armv7ve 開啟.
  • 新增 ARMv8-A 加密以及 CRC 的 intrinsic, 目前要透過 -march=armv8-a+crc 以及 -mfpu=crypto-neon-fp-armv8 來開啟.
  • ARM 現在預設開啟 LRA, 可以透過 -mno-lra 來關掉, 這個選項指示拿來方便發現 bug 或 performance regressions 用的, 未來會拔除.
  • 加入新選項 -mslow-flash-data: 可改善在 ARMv7-M profile cores 上的程式效能.
  • 加入新選項 -mpic-data-is-text-relative 來讓 text segment 可透過相對位址存取 data segment, 目前除了 VxWorks RTP 外預設開啟.
  • 大量的基礎建設改善使得 ARM 以及 AArch64 的 Code Gen 獲得不思議的改善.
  • GCC 現在支援 Cortex-A12 以及 Cortex-R7: -mcpu=cortex-a12 及 -mcpu=cortex-r7 選項.
  • GCC 現在支援 Cortex-A57 以及 Cortex-A53: -mcpu=cortex-a57 及 -mcpu=cortex-a53 選項.
  • 初步 big.LITTLE 微調可整合 Cortex-A57 以及 Cortex-A53, 可透過 -mcpu=cortex-a57.cortex-a53 來開啟.
  • 新增更多針對 Cortex-A15 以及 the Cortex-M4 的效能改善
  • 針對 M-profile processors 改善 Thumb2 的 Code Gen

IA-32/x86-64

  • 支援 AVX-512 指令集, 支援 inline assembly, 新的 registers 以及延伸舊有的東西, 新的 intrinsics (包含相對應的 testsuite), 以及基本的自動向量化. AVX-512 指令目前可透過以下 GCC 選項開啟: AVX-512 foundation instructions: -mavx512f, AVX-512 prefetch instructions: -mavx512pf, AVX-512 exponential 以及 reciprocal instructions: -mavx512er, AVX-512 conflict detection instructions: -mavx512cd.
  • 現在可以針對特定函數打上相對應的 target attribute 而不用整個檔案用 -mxxx 選項來使得整的檔案來指定特定 target, 這使得單一檔案中容易實作 Function Multiversioning.
  • GCC 現在支援 Silvermont: -march=silvermont.
  • GCC 現在支援 Broadwell: -march=broadwell.
  • -march 部份重新命名: -march=nehalem, westmere, sandybridge, ivybridge, haswell, bonnell
  • -march=generic 現在針對 Intel core and AMD Bulldozer architectures 提供更好的效能, AMD K7, K8, Intel Pentium-M, and Pentium4 based 的 CPU 效能不再重要.
  • -mtune=intel 可以針對大部分的 Intel cpu 產生更好的 Code.
  • 支援將 32-bit assembly instructions encode 成 16-bit, 可透過 -m32 開啟.
  • 更好的 memcpy 及 memset, 會針對長度以及內容物產生更短的 alignment prologues.
  • -mno-accumulate-outgoing-args 現在會產生更精確的 unwind 資訊. 針對 -Os, Argument accumulation 將預設關閉.
  • 支援 AMD 家族的 15h processors (Excavator core): -march=bdver4 以及 -mtune=bdver4.

NDS32

  • 新的 nds32 port, 一個來自台灣晶心科技的 32-bit 架構.
  • 目前的 Porting 初步支援 V2, V3, V3m instruction set architectures.