使用 -qoptdebug 來協助除錯最佳化程式

-qoptdebug 編譯器選項的目的是協助對最佳化程式進行除錯。 它透過建立虛擬程式碼來執行此動作,該虛擬程式碼會比原始程式碼更接近最佳化程式的指令及值。 當使用 -qoptdebug 編譯的程式載入除錯器時,您將進行虛擬程式碼除錯,而不是原始程式碼除錯。 透過在虛擬程式碼中明確最佳化,您可以更充分地瞭解您的程式在最佳化下的實際行為。 包含程式虛擬碼的檔案會以檔案字尾產生.optdbg。此特性僅支援行除錯。

附註: 編譯器已引進 -g 的支援,以在完整除錯支援與最佳化之間提供各種層次的平衡支援。 如果您想要在利用編譯器最佳化時對原始碼進行除錯,請使用 -g 而非 -qoptdebug。 如需相關資訊,請參閱 -g
如下列範例所示編譯您的程式:
xlf myprogram.f -O3 -qhot -g -qoptdebug
在此範例中,您的原始檔會編譯至 a.out。 最佳化程式的虛擬碼會寫入稱為的檔案中myprogram.optdbg,當您除錯程式時可以參照。
附註:
  • 還必須指定 -g-qlinedebug 選項,才能讓已編譯的執行檔可除錯。 不過,如果這兩個選項都未指定,則虛擬碼檔案<output_file>.optdbg仍會產生包含最佳化虛擬碼的。
  • 僅當指定了一個以上最佳化選項 -qhot-qsmp-qpdf-qipa ,或者指定了暗示這些選項的最佳化等級 (即最佳化等級 -O3-O4-O5) 時, -qoptdebug 選項才會生效。 範例顯示最佳化選項 -qhot-O3

除錯最佳化程式

從下列範例中,您可以看到編譯器如何將最佳化套用至簡式程式,以及它與除錯原始程式有何不同。

範例 1: 代表簡式程式的原始非最佳化程式碼。 它為編譯器提供了一些最佳化機會。 例如,變數 zd 都由對等表示式指派 x + y。 因此,這兩個變數可以合併在最佳化來源中。 此外,也可以解除捲動迴圈。 在最佳化來源中,您可以看到明確列出迴圈的反覆運算。

範例 2: 代表除錯器中所示的最佳化原始檔清單。 請注意未捲動的迴圈,以及 x + y 表示式指派的值合併。

範例 3: 顯示使用除錯器逐步執行最佳化原始檔的範例。 請注意,相較於原始來源中的行號,在最佳化來源中這些陳述式的行號之間不再有對應。

範例 1: 原始程式碼
      FUNCTION FOO(X, Y)
      Z = X + Y
      D = X + Y
      DO I = 1, 4
        PRINT *, D, Z
      END DO
      FOO = X + Y
      END FUNCTION

      PROGRAM MAIN
      CALL FOO(3.0, 4.0)
      END PROGRAM MAIN
範例 2: dbx 除錯器清單
(dbx) list
    1
    2
    3        1|         REAL*4 FUNCTION foo (x, y)
    4        1|           @CSE2 = x
    5                     @CSE1 = y
    6        5|           #2 = _xlfBeginIO(6,257,#1,1024,NULL,0,NULL)
    7                     @CSE0 = @CSE2 + @CSE1
    8                     #3 = @CSE0
    9                     CALL _xlfWriteLDReal(%VAL(#2),#3,4,4)
   10                     #4 = @CSE0
   11                     CALL _xlfWriteLDReal(%VAL(#2),#4,4,4)
   12                     _xlfEndIO(%VAL(#2))
   13                     #2 = _xlfBeginIO(6,257,#1,1024,NULL,0,NULL)
   14                     #3 = @CSE0
   15                     CALL _xlfWriteLDReal(%VAL(#2),#3,4,4)
   16                     #4 = @CSE0
   17                     CALL _xlfWriteLDReal(%VAL(#2),#4,4,4)
   18                     _xlfEndIO(%VAL(#2))
   19                     #2 = _xlfBeginIO(6,257,#1,1024,NULL,0,NULL)
   20                     #3 = @CSE0
   21                     CALL _xlfWriteLDReal(%VAL(#2),#3,4,4)
   22                     #4 = @CSE0
   23                     CALL _xlfWriteLDReal(%VAL(#2),#4,4,4)
   24                     _xlfEndIO(%VAL(#2))
   25                     #2 = _xlfBeginIO(6,257,#1,1024,NULL,0,NULL)
   26                     #3 = @CSE0
   27                     CALL _xlfWriteLDReal(%VAL(#2),#3,4,4)
   28                     #4 = @CSE0
   29                     CALL _xlfWriteLDReal(%VAL(#2),#4,4,4)
   30                     _xlfEndIO(%VAL(#2))
   31        8|           RETURN
   32                   END FUNCTION foo
   33
   34
   35       10|         PROGRAM main ()
   36       11|           T_3 =  3.00000000E+00
   37                     T_4 =  4.00000000E+00
   38                     CALL foo(T_3,T_4)
   39       12|           CALL _xlfExit(0)
   40                     CALL _trap(3)
   41                   END PROGRAM main
範例 3: 逐步執行最佳化來源
(dbx) stop at 17
[1] stop at "myprogram.o.rptdbg":17
(dbx) cont
 7.000000000 7.000000000
[1] stopped in foo at line 17 in file "myprogram.o.rptdbg"
   17                     CALL _xlfWriteLDReal(%VAL(#2),#4,4,4)
(dbx) step
 7.000000000 7.000000000
stopped in foo at line 18 in file "myprogram.o.rptdbg"
   18                     _xlfEndIO(%VAL(#2))
(dbx) step
stopped in foo at line 20 in file "myprogram.o.rptdbg"
   20                     #3 = @CSE0
(dbx) step
stopped in foo at line 22 in file "myprogram.o.rptdbg"
   22                     #4 = @CSE0
(dbx) step
stopped in foo at line 23 in file "myprogram.o.rptdbg"
   23                     CALL _xlfWriteLDReal(%VAL(#2),#4,4,4)
(dbx) step
 7.000000000 7.000000000
stopped in foo at line 24 in file "myprogram.o.rptdbg"
   24                     _xlfEndIO(%VAL(#2))
(dbx) step
stopped in foo at line 26 in file "myprogram.o.rptdbg"
   26                     #3 = @CSE0
(dbx) cont
 7.000000000 7.000000000

execution completed