Python在嵌入式應(yīng)用程序開發(fā)中變得越來越普遍,特別是對于在網(wǎng)絡(luò)邊緣運行的機器學(xué)習(xí)框架。但是,這種高級通用編程語言抽象出代碼中的許多細節(jié),這些細節(jié)可能會以開發(fā)人員可能沒有意識到的方式影響實現(xiàn)的性能。
讓我們舉一個明顯的例子:計算斐波那契數(shù)列。至少有兩種不同的方法可以執(zhí)行此操作,遞歸算法和標(biāo)準(zhǔn)迭代算法,其性能級別差異很大。
可以使用名為跟蹤測試器的工具評估不同實現(xiàn)或算法的性能。這是Percepio的可視化跟蹤診斷工具,使嵌入式軟件開發(fā)人員能夠在運行時深入了解代碼,以便更輕松地調(diào)試系統(tǒng)級問題,并幫助他們改進軟件的設(shè)計和性能。
Tracealyzer 可以與開源 Eclipse 工具等傳統(tǒng)調(diào)試器并排使用,并通過系統(tǒng)級的幾個附加視圖補充詳細的調(diào)試器視圖。這有助于了解經(jīng)典調(diào)試器不足的實時問題。
結(jié)合 Linux 操作系統(tǒng)發(fā)行版中的 LTTng 開源跟蹤包,跟蹤測試程序可以顯示不同級別的性能。這與處理器無關(guān),并且是所選算法的結(jié)果。
對于評估,斐波那契數(shù)列的每個實現(xiàn)都在單個模塊中執(zhí)行:
def recur_fibo(n):
if n <=1 n:
return n
else:
return(recur_fibo(n-1) + recur_fibo(n-2))
def non_recur_fibo(n):
result = []
a,b = 0,1
while a < n:
result.append(a)
a,b = b, a+b
return result
有單獨的Python源文件調(diào)用上面的兩個函數(shù):
import lttngust
import logging
import fib
def example():
logging.basicConfig()
logger = logging.getLogger(‘my-logger’)
logger.info(‘Start’)
fib.recur_fibo(10)
logger.info(‘Stop’)
logger.info(‘Start’)
fib.non_recur_fibo(10)
logger.info(‘Stop’)
if __name__ == ‘__main__’:
example()
以下命令在 LTTng 中捕獲跟蹤,然后可以在跟蹤測試器中對其進行檢查:
$> lttng create
$> lttng enable-event --kernel sched_switch
$> lttng enable-event --python my-logger
$> lttng start
$> python3 .py
$> lttng stop
$> lttng destroy
將標(biāo)準(zhǔn)的 Python 記錄器替換為稱為“我的記錄器”,允許跟蹤測試程序在工具的跟蹤視圖中顯示事件。由于 Tracealyzer 在此特定示例中未捕獲任何應(yīng)用程序數(shù)據(jù),因此無需將軟件配置為讀取數(shù)據(jù)值。相反,所需要的只是一個自定義間隔,用于標(biāo)記兩個函數(shù)的進入和退出。
雖然在上面的跟蹤視圖中可以看到巨大的性能差異,但 Tracealyzer 還可以提供更多有形的性能指標(biāo)。這可以通過轉(zhuǎn)到視圖并單擊“間隔”和“狀態(tài)機”來完成,并使用代碼中隨 logger.info()調(diào)用一起插入的“開始”和“停止”字符串創(chuàng)建自定義間隔,這些字符串標(biāo)記候選函數(shù)的進入和退出。
區(qū)間圖顯示遞歸算法(首先執(zhí)行)和迭代算法(第二次執(zhí)行)之間存在 20 倍的差異。
在這個例子中,我們用每個算法只計算10個斐波那契數(shù)列。如果沒有 Tracealyzer,可能需要進行更多的迭代才能獲得一些有意義的見解,但由于兩個原因,這是有問題的。首先,當(dāng)將遞歸斐波那契算法運行到1000(甚至100)時,Python將簡單地坐在那里。這將是令人擔(dān)憂的,因為不清楚這種無響應(yīng)是由于實現(xiàn)中的錯誤還是其他原因造成的。在這種情況下,我們可能可以猜測為什么會發(fā)生這種情況,但是對于更復(fù)雜的問題,需要大量的日志記錄才能了解瓶頸的位置。
其次,如果嵌入式系統(tǒng)上運行多個應(yīng)用程序,則這些其他應(yīng)用程序可能會破壞目標(biāo)應(yīng)用程序,這也會增加算法或函數(shù)完成執(zhí)行的時間。沒有痕跡,就沒有簡單的方法來找出是否是這種情況。
相反,Python和跟蹤測試器中LTTng的組合突出了所選擇算法的基本特征才是問題所在。在開發(fā)更復(fù)雜的算法時,這是非常寶貴的。此示例實現(xiàn)可作為有關(guān)如何評估未來算法實現(xiàn)性能的參考。一般來說,在單獨的Python模塊中實現(xiàn)核心功能是良好的編程實踐,這也簡化了特定功能的跟蹤。
由于跟蹤開銷幾乎可以忽略不計,因此跟蹤點可以保留在應(yīng)用程序中,因為它在目標(biāo)嵌入式系統(tǒng)上甚至在生產(chǎn)中進行測試,從而允許 Tracealyzer 工具在生產(chǎn)代碼庫中生成性能指標(biāo)。這對于常規(guī)系統(tǒng)測試非常有用,并且允許使用相同的代碼庫來確保應(yīng)用程序在功能上正確且性能良好,只需進行最少的更改。
結(jié)論
使用跟蹤測試程序和 LTTng 在 Python 應(yīng)用程序中捕獲性能指標(biāo),可以對算法的實現(xiàn)進行寶貴的分析。
這種方法的開銷最小,這意味著可以保留代碼的檢測,以便在目標(biāo)嵌入式系統(tǒng)上使用。這樣可以對目標(biāo)應(yīng)用程序進行更多監(jiān)視,并增強與其他應(yīng)用程序和操作系統(tǒng)的交互分析。例如,可能有另一個進程或線程搶占目標(biāo)應(yīng)用程序并影響性能。跟蹤測試程序和 LTTng 的組合可以識別此類異常的原因,這使開發(fā)人員能夠優(yōu)化實現(xiàn)以防止進一步的問題。
雖然斐波那契數(shù)列的示例實現(xiàn)相對無害,但它突出了Python語言的一個關(guān)鍵特征,可以為開發(fā)更復(fù)雜的實現(xiàn)提供信息。
此示例還顯示了在設(shè)計中使用單獨模塊的價值。使用 trace,開發(fā)人員可以在擴展到完整的系統(tǒng)實現(xiàn)之前,在這些模塊中測量和驗證關(guān)鍵核心功能的性能,而不會產(chǎn)生顯著的開銷。這有助于證明應(yīng)用程序在功能上是正確的,并且在目標(biāo)環(huán)境中進行最小的更改時性能良好。
審核編輯:郭婷
-
嵌入式
+關(guān)注
關(guān)注
5146文章
19599瀏覽量
316310 -
python
+關(guān)注
關(guān)注
56文章
4825瀏覽量
86476
發(fā)布評論請先 登錄
評論