使用 -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: 代表簡式程式的原始非最佳化程式碼。 它為編譯器提供了一些最佳化機會。 例如,變數 z 和 d 都由對等表示式指派 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