一種簡單、實用的測量程序運行時間的方法

點擊上方「嵌入式大雜燴」,選擇「置頂公衆號」第一時間查看嵌入式筆記!

前言

平時我們可能很少去關注程序運行的時間,但是在一些情況下可能需要對程序進行一個整體的覆盤、優化。

那麼,程序運行的時間就是一個可以考慮的方面,可以測一下某些代碼塊、函數、算法的運行時間,然後整體考慮看看有沒有必要進行優化。

之前在某工控類項目中,我就有接到一個任務去測試程序中關鍵代碼的執行時間,並輸出報告。當時是使用一個GPIO+示波器進行測試的,也可以使用邏輯分析儀來測。

當時測量的方法很簡單:

在要測試的代碼塊/函數之前設置該GPIO的電平爲高電平,在要測試的代碼塊/函數之後設置該GPIO爲低電平,使用示波器測高電平的時間,就知道了這一代碼塊/函數的運行時間。

下面就通過實例來介紹一下這種簡單而有效的方法。

我這裏使用邏輯分析儀來測量,使用小熊派開發板來驗證,小熊派的主控爲STM32L431RCT6,系統時鐘設置爲80MHz

這裏順帶提一點題外話,之前有一些初學的讀者朋友問我說邏輯分析儀貴不貴。邏輯分析儀有貴的也有便宜的,貴則上千上萬元,便宜則有幾十、幾百。我覺得無論工作、還是學習,都有必要入手一個邏輯分析儀。

本篇筆記的測試用的邏輯分析儀就是某寶上二十幾塊錢買的,可以滿足平時的學習所用。條件有限的學生朋友可以入手。有條件的可以考慮入手幾百塊錢的。

GPIO+邏輯分析儀測時間

1、測量HAL_Delay函數

STM32的HAL庫有給我們提供一個HAL_Delay延時函數,這是一個ms級延時函數。這個延時函數依賴於系統滴答定時器,所以是一個比較精確的延時函數。

這裏,我們就使用GPIO+邏輯分析儀的方法來測量一下這個延時函數。爲了方便測試,我們在while死循環裏進行測量。

代碼:

測量結果:

可見,我們通過邏輯分析儀測出了HAL_Delay(100);運行的時間爲100.4315ms,符合我們的預期。

這裏高電平兩側其實就是低電平部分,只不過低電平持續的時間太短了,在這裏看起來像一條豎線,我們放大來看看:

結果已經很準了,可以滿足平時的測量。這種測量很難保證百分之百的精確,小數點後面的那一部分可能是受很多不可控因素的影響,這不在我們本篇文章的討論範圍之內。

我們是想通過這個示例來介紹這種測量方法的使用及證明這種方法是可行的。下面再繼續看兩個實例。

2、測量軟件延時函數

我們以前剛開始學單片機的時候,經常有用到一些粗略的延時函數,其實現方法就是循環執行n條空語句,以達到一個延時的效果。

那麼,我們怎麼來構造一個us級或ms級的粗略延時函數(軟件延時函數)。我們之前看到的粗略延時函數類似這樣子:

這些函數裏面需要給出一些循環的次數,這個值是怎麼來確定的呢?比如上面這個函數中123這個值是怎麼來確定的?我們可以使用GPIO+邏輯分析儀的方法來進行一個簡單的確定。

確定1us:

不同的處理器,結果是不一樣的。針對小熊派開發板(主控:STM32L431RCT6),循環運行15條空語句的時間實測結果是1.083us,這算是比較接近1us了。

我們就運用這個結果來構建一個us級軟件延時函數如下:

接下來我們測一下soft_delay_us(100);實際運行了多長時間:

可見,結果差不多接近我們想要的結果。構建這樣的粗略延時函數可以使用這樣的方式來確定一些循環次數的值。

3、查表法VS常規法運行時間

在之前的文章:空間換時間,查表法的經典例子《空間換時間,查表法的經典例子》中,我們有說可以適當使用查表法降低程序的執行時間。這裏我們來實際測量對比一下那篇文章中查表法與常規法的優劣。

關鍵代碼:

/* 測試結果 */
struct test_res
{
 unsigned int data;  /* 數據          */
 unsigned int count; /* 數據中1的個數 */
};

/* ============常規法============ */
#if 1
struct test_res get_test_res(unsigned int data)
{
 /* 保存測試結果 */
 struct test_res res;
 
 /* 保證數據總會在0~0xf之間 */
 // unsigned int temp = data & 0xf;  
 unsigned int temp = data & 0xff;  
 
 res.count = 0;
 res.data = temp;
 
 /* 循環判斷每一位 */
 for (int i = 0; i < 16; i++)
 {
  if (temp & 0x01)
  {
   res.count++;
  }
  temp >>= 1;
 }
 
 return res;
}
#else
/* ============查表法============ */

int table[16] = {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};

struct test_res get_test_res(unsigned int data)
{
 /* 保存測試結果 */
 struct test_res res;
 
 /* 保證數據總會在0~0xf之間 */
 unsigned int temp = data & 0xff;  
 
 /* 獲取低4位中1的個數 */
 unsigned int low_data = temp & 0xf;
 unsigned int low_cnt = table[low_data];
 
 /* 獲取高4位中1的個數 */
 unsigned int high_data = (temp >> 4) & 0xf;
 unsigned int high_cnt = table[high_data];
 
 /* 結果 */
 res.count = low_cnt + high_cnt;
 res.data = temp;
 
 return res;
}

int main(void)
{
  /* USER CODE BEGIN 1 */
  struct test_res res = {0};
    
  /* 省略部分代碼。。。。。。。。。 */
    
  while (1)
  {
  /* USER CODE END WHILE */
  /* USER CODE BEGIN 3 */
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_SET);
    res = get_test_res(30);
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_RESET);
  }
  /* USER CODE END 3 */
}
#endif

常規法程序的運行時間:

查表法程序的運行時間:

可見,這個例子中常規法程序運行時間約爲2ns,而查表法程序運行時間約爲500ns。查表法的程序運行之間僅爲常規法的1/4,省下了3/4的時間。

隨着調用次數的增多,這裏的查表法的優勢越大。比如循環計算0~31這32個數中每一個數二進制位爲1的個數,則相關代碼改爲:

  int i;
  while (1)
  {
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_SET);
    for (i = 0; i < 32; i++)
    {
      res = get_test_res(i);
    }
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_RESET);
  }

常規法:

查表法:

可見,隨着調用次數的增多,查表法相對於常規法更省時,即查表法的優勢越大。

以上就是關於GPIO+邏輯分析儀測程序運行時間的幾個實例。下面順帶提一下使用MDK+ST-LINK測STM32程序運行時間的方法。

MDK+ST-LINK測時間

在使用MDK作爲開發工具時,可以搭配一些仿真器來查看程序執行時間。這裏通過實例來介紹MDK+ST-LINK測STM32程序運行時間的方法。

這裏重點是設置Trace裏面的系統內核時鐘,我們這裏使用的是小熊派開發板(主控:STM32L431RCT6),並且配置的系統時鐘是80MHz:

所以在Trace中要設置爲80MHz。這個得根據實際芯片的型號就需要根據進行修改,比如STM32F103系列默認是72MHz,STM32F429系列默認爲180MHz等,根據實際進行修改。

下面我們通過在線調試、打斷點的方式看一下 HAL_Delay(1000);運行了多長時間:

可見程序運行到HAL_Delay(1000);前後的時間分別爲:

前:0.00008964s
後:1.00108161s

HAL_Delay(1000);走過的時間約爲1s,符合預期。

最後

以上就是本次的實踐分享,感謝閱讀與支持。如有錯誤,歡迎指出。謝謝!

若覺得文章不錯,轉發分享、在看,也是我們繼續更新的動力。

在公衆號內回覆更多資源,可免費獲取嵌入式資料。期待你的關注~

猜你喜歡

C語言、嵌入式應用:TCP通信實例分析

一些不可不知的計算機網絡基礎

AT指令測試ESP8266通信模組並獲取天氣數據

在SRAM、FLASH中調試代碼的配置方法

STM32串口IAP分享

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章