mirror of
https://github.com/GorgonMeducer/perf_counter.git
synced 2025-02-07 19:34:18 +08:00
update document
This commit is contained in:
parent
7f4293f992
commit
0591cdb245
134
README.md
134
README.md
@ -1,4 +1,4 @@
|
|||||||
# perf_counter (v2.3.0-dev)
|
# perf_counter (v2.3.0)
|
||||||
A dedicated performance counter for Cortex-M Systick. It shares the SysTick with users' original SysTick function(s) without interfering with it. This library will bring new functionalities, such as performance counter,` delay_us` and `clock()` service defined in `time.h`.
|
A dedicated performance counter for Cortex-M Systick. It shares the SysTick with users' original SysTick function(s) without interfering with it. This library will bring new functionalities, such as performance counter,` delay_us` and `clock()` service defined in `time.h`.
|
||||||
|
|
||||||
### Features:
|
### Features:
|
||||||
@ -10,14 +10,14 @@ A dedicated performance counter for Cortex-M Systick. It shares the SysTick with
|
|||||||
- Measures **RAW / True** cycles used for specified code segment inside a thread, **i.e. scheduling cost are removed**.
|
- Measures **RAW / True** cycles used for specified code segment inside a thread, **i.e. scheduling cost are removed**.
|
||||||
- Measure **RAW/True** cycles used for a data-process-path across multiple threads.
|
- Measure **RAW/True** cycles used for a data-process-path across multiple threads.
|
||||||
- **Easy to use**
|
- **Easy to use**
|
||||||
- Helper macros: `__cycleof__()` , `__super_loop_monitor__()` etc.
|
- Helper macros: `__cycleof__()` , `__super_loop_monitor__()` , `__cpu_usage__()`, `__cpu_perf__()` etc.
|
||||||
- Helper functions: `start_cycle_counter()`, `stop_cycle_counter()` etc.
|
- Helper functions: `start_cycle_counter()`, `stop_cycle_counter()` etc.
|
||||||
- Enable a broader processor architecture support
|
- Enable a broader processor architecture support
|
||||||
- **Support ALL Cortex-M processors**
|
- **Support ALL Cortex-M processors**
|
||||||
- SysTick
|
- SysTick
|
||||||
- **[new]**Performance Monitor Unit (PMU)
|
- **[new]**Performance Monitor Unit (PMU)
|
||||||
|
|
||||||
- **[new]**Easy to port to different architectures with a porting template
|
- **[new]**Easy to port to a different architecture with a porting template
|
||||||
|
|
||||||
- **Provide Free Services**
|
- **Provide Free Services**
|
||||||
- Do **NOT** interfer with existing SysTick based applications
|
- Do **NOT** interfer with existing SysTick based applications
|
||||||
@ -64,7 +64,7 @@ __cycleof__(<Description String for the target>, [User Code, see ref 1]) {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Here, [**ref 1**] is a small user code to read the measurement result via a local variable `__cycle_count__` for perl lovers, you can also use "`_`" to read the result. This User Code is optional. If you don't put anything here, the measured result will be shown with a `printf()`.
|
Here, [**ref 1**] is a small user code to read the measurement result via a local variable `__cycle_count__` . This User Code is optional. If you don't put anything here, the measured result will be shown with a `__perf_counter_printf__`.
|
||||||
|
|
||||||
#### **Example 1:** Simple measurement with printf
|
#### **Example 1:** Simple measurement with printf
|
||||||
|
|
||||||
@ -103,9 +103,123 @@ The result is read out from `__cycle_count__`and used in other place:
|
|||||||
|
|
||||||
![image-20220509004714845](./documents/pictures/__cycleof___output_non_printf)
|
![image-20220509004714845](./documents/pictures/__cycleof___output_non_printf)
|
||||||
|
|
||||||
|
### 1.2 Performance Analysis
|
||||||
|
|
||||||
|
#### 1.2.1 CPU Usage
|
||||||
|
|
||||||
|
For both bare-metal and OS environment, you can measure the CPU Usage with macro `__cpu_usage__()` for a given code segment as long as it is executed repeatedly.
|
||||||
|
|
||||||
|
**Syntax**
|
||||||
|
|
||||||
|
```c
|
||||||
|
__cycleof__(<Iteration Count before getting an average result>, [User Code, see ref 1]) {
|
||||||
|
//! target code segment of measurement
|
||||||
|
...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Here, [**ref 1**] is a small user code to read the measurement result via a local variable `__usage__`. This User Code is optional. If you don't put anything here, the measured result will be shown with a `__perf_counter_printf__`.
|
||||||
|
|
||||||
|
##### **Example 1: the following code will show 30% of CPU Usage:**
|
||||||
|
|
||||||
|
```c
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
...
|
||||||
|
while (1) {
|
||||||
|
__cpu_usage__(10) {
|
||||||
|
delay_us(30000);
|
||||||
|
}
|
||||||
|
delay_us(70000);
|
||||||
|
}
|
||||||
|
...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
##### Example 2: Read measurement result via `__usage__`
|
||||||
|
|
||||||
|
```c
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
...
|
||||||
|
while (1) {
|
||||||
|
|
||||||
|
float fUsage = 0.0f;
|
||||||
|
__cpu_usage__(10, {
|
||||||
|
fUsage = __usage__; /*< "__usage__" stores the result */
|
||||||
|
}) {
|
||||||
|
delay_us(30000);
|
||||||
|
}
|
||||||
|
printf("task 1 cpu usage %3.2f %%\r\n", (double)fUsage);
|
||||||
|
|
||||||
|
delay_us(70000);
|
||||||
|
}
|
||||||
|
...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
NOTE: The `__usage__` stores the percentage information.
|
||||||
|
|
||||||
|
|
||||||
### 1.2 Timestamp
|
|
||||||
|
#### 1.2.2 Cycle per Instruction and L1 DCache Miss Rate
|
||||||
|
|
||||||
|
For **Armv8.1-m** processors that implement the **PMU**, it is easy to measure the **CPI** (Cycle per Instruction) and **L1 DCache miss rate** with the macro `__cpu_perf__()`.
|
||||||
|
|
||||||
|
**Syntax**:
|
||||||
|
|
||||||
|
```c
|
||||||
|
__cpu_perf__(<Description String for the target>, [User Code, see ref 1]) {
|
||||||
|
//! target code segment of measurement
|
||||||
|
...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Here, [**ref 1**] is a small user code to read the measurement result via a local **struct** variable `__PERF_INFO__` . This User Code is optional. If you don't put anything here, the measured result will be shown with a `__perf_counter_printf__`. The prototype of the `__PERF_INFO__` is shown below:
|
||||||
|
|
||||||
|
```c
|
||||||
|
struct {
|
||||||
|
uint64_t dwNoInstr; /* number of instruction executed */
|
||||||
|
uint64_t dwNoMemAccess; /* number of memory access */
|
||||||
|
uint64_t dwNoL1DCacheRefill; /* number of L1 DCache Refill */
|
||||||
|
int64_t lCycles; /* number of CPU cycles */
|
||||||
|
uint32_t wInstrCalib;
|
||||||
|
uint32_t wMemAccessCalib;
|
||||||
|
float fCPI; /* Cycle per Instruction */
|
||||||
|
float fDCacheMissRate; /* L1 DCache miss rate in percentage */
|
||||||
|
} __PERF_INFO__;
|
||||||
|
```
|
||||||
|
|
||||||
|
For example, when insert user code, you can read CPI from `__PERF_INFO__.fCPI`.
|
||||||
|
|
||||||
|
**Example 1: measure the Coremark**
|
||||||
|
|
||||||
|
```c
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
init_cycle_counter(false);
|
||||||
|
|
||||||
|
printf("Run coremark\r\n");
|
||||||
|
|
||||||
|
#ifdef __PERF_COUNTER_COREMARK__
|
||||||
|
__cpu_perf__("Coremark") {
|
||||||
|
coremark_main();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
__NOP();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The result might look like the following:
|
||||||
|
|
||||||
|
![](./documents/pictures/__cpu_perf__output.png)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### 1.3 Timestamp
|
||||||
|
|
||||||
You can get the system timestamp (since the initialization of perf_counter service) via function `get_system_ticks()` and `get_system_ms()`.
|
You can get the system timestamp (since the initialization of perf_counter service) via function `get_system_ticks()` and `get_system_ms()`.
|
||||||
|
|
||||||
@ -176,7 +290,7 @@ This example shows how to use the delta value of `get_system_ticks()` to measure
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
### 1.3 Timer Services
|
### 1.4 Timer Services
|
||||||
|
|
||||||
perf_counter provides the basic timer services for delaying a given period of time and polling-for-timeout. For example:
|
perf_counter provides the basic timer services for delaying a given period of time and polling-for-timeout. For example:
|
||||||
|
|
||||||
@ -197,7 +311,7 @@ while(1) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
### 1.4 Work with EventRecorder in MDK
|
### 1.5 Work with EventRecorder in MDK
|
||||||
|
|
||||||
If you are using EventRecorder in MDK, once you deployed the `perf_counter`, it will provide the timer service for EventRecorder by implenting the following functions: `EventRecorderTimerSetup()`, `EventRecorderTimerGetFreq()` and `EventRecorderTimerGetCount()`.
|
If you are using EventRecorder in MDK, once you deployed the `perf_counter`, it will provide the timer service for EventRecorder by implenting the following functions: `EventRecorderTimerSetup()`, `EventRecorderTimerGetFreq()` and `EventRecorderTimerGetCount()`.
|
||||||
|
|
||||||
@ -217,9 +331,9 @@ Please set the macro `EVENT_TIMESTAMP_SOURCE` to `3` to suppress it.
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
### 1.5 On System Environment Changing
|
### 1.6 On System Environment Changing
|
||||||
|
|
||||||
#### 1.5.1 System Frequency Changing
|
#### 1.6.1 System Frequency Changing
|
||||||
|
|
||||||
If you want to change the System Frequency, **after** the change, make sure:
|
If you want to change the System Frequency, **after** the change, make sure:
|
||||||
|
|
||||||
@ -229,7 +343,7 @@ If you want to change the System Frequency, **after** the change, make sure:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
#### 1.5.2 Reconfigure the SysTick
|
#### 1.6.2 Reconfigure the SysTick
|
||||||
|
|
||||||
Some systems (e.g. FreeRTOS) might reconfigure the systick timer to fulfil the requirement of their feature. To support this:
|
Some systems (e.g. FreeRTOS) might reconfigure the systick timer to fulfil the requirement of their feature. To support this:
|
||||||
|
|
||||||
|
BIN
documents/pictures/__cpu_perf__output.png
Normal file
BIN
documents/pictures/__cpu_perf__output.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 14 KiB |
@ -768,18 +768,6 @@
|
|||||||
<File>
|
<File>
|
||||||
<GroupNumber>2</GroupNumber>
|
<GroupNumber>2</GroupNumber>
|
||||||
<FileNumber>7</FileNumber>
|
<FileNumber>7</FileNumber>
|
||||||
<FileType>4</FileType>
|
|
||||||
<tvExp>0</tvExp>
|
|
||||||
<tvExpOptDlg>0</tvExpOptDlg>
|
|
||||||
<bDave2>0</bDave2>
|
|
||||||
<PathWithFileName>..\lib\perf_counter.lib</PathWithFileName>
|
|
||||||
<FilenameWithoutPath>perf_counter.lib</FilenameWithoutPath>
|
|
||||||
<RteFlg>0</RteFlg>
|
|
||||||
<bShared>0</bShared>
|
|
||||||
</File>
|
|
||||||
<File>
|
|
||||||
<GroupNumber>2</GroupNumber>
|
|
||||||
<FileNumber>8</FileNumber>
|
|
||||||
<FileType>1</FileType>
|
<FileType>1</FileType>
|
||||||
<tvExp>0</tvExp>
|
<tvExp>0</tvExp>
|
||||||
<tvExpOptDlg>0</tvExpOptDlg>
|
<tvExpOptDlg>0</tvExpOptDlg>
|
||||||
@ -791,7 +779,7 @@
|
|||||||
</File>
|
</File>
|
||||||
<File>
|
<File>
|
||||||
<GroupNumber>2</GroupNumber>
|
<GroupNumber>2</GroupNumber>
|
||||||
<FileNumber>9</FileNumber>
|
<FileNumber>8</FileNumber>
|
||||||
<FileType>5</FileType>
|
<FileType>5</FileType>
|
||||||
<tvExp>0</tvExp>
|
<tvExp>0</tvExp>
|
||||||
<tvExpOptDlg>0</tvExpOptDlg>
|
<tvExpOptDlg>0</tvExpOptDlg>
|
||||||
|
@ -408,57 +408,6 @@
|
|||||||
<FileName>perf_counter.c</FileName>
|
<FileName>perf_counter.c</FileName>
|
||||||
<FileType>1</FileType>
|
<FileType>1</FileType>
|
||||||
<FilePath>..\perf_counter.c</FilePath>
|
<FilePath>..\perf_counter.c</FilePath>
|
||||||
<FileOption>
|
|
||||||
<CommonProperty>
|
|
||||||
<UseCPPCompiler>2</UseCPPCompiler>
|
|
||||||
<RVCTCodeConst>0</RVCTCodeConst>
|
|
||||||
<RVCTZI>0</RVCTZI>
|
|
||||||
<RVCTOtherData>0</RVCTOtherData>
|
|
||||||
<ModuleSelection>0</ModuleSelection>
|
|
||||||
<IncludeInBuild>0</IncludeInBuild>
|
|
||||||
<AlwaysBuild>2</AlwaysBuild>
|
|
||||||
<GenerateAssemblyFile>2</GenerateAssemblyFile>
|
|
||||||
<AssembleAssemblyFile>2</AssembleAssemblyFile>
|
|
||||||
<PublicsOnly>2</PublicsOnly>
|
|
||||||
<StopOnExitCode>11</StopOnExitCode>
|
|
||||||
<CustomArgument></CustomArgument>
|
|
||||||
<IncludeLibraryModules></IncludeLibraryModules>
|
|
||||||
<ComprImg>1</ComprImg>
|
|
||||||
</CommonProperty>
|
|
||||||
<FileArmAds>
|
|
||||||
<Cads>
|
|
||||||
<interw>2</interw>
|
|
||||||
<Optim>0</Optim>
|
|
||||||
<oTime>2</oTime>
|
|
||||||
<SplitLS>2</SplitLS>
|
|
||||||
<OneElfS>2</OneElfS>
|
|
||||||
<Strict>2</Strict>
|
|
||||||
<EnumInt>2</EnumInt>
|
|
||||||
<PlainCh>2</PlainCh>
|
|
||||||
<Ropi>2</Ropi>
|
|
||||||
<Rwpi>2</Rwpi>
|
|
||||||
<wLevel>0</wLevel>
|
|
||||||
<uThumb>2</uThumb>
|
|
||||||
<uSurpInc>2</uSurpInc>
|
|
||||||
<uC99>2</uC99>
|
|
||||||
<uGnu>2</uGnu>
|
|
||||||
<useXO>2</useXO>
|
|
||||||
<v6Lang>0</v6Lang>
|
|
||||||
<v6LangP>0</v6LangP>
|
|
||||||
<vShortEn>2</vShortEn>
|
|
||||||
<vShortWch>2</vShortWch>
|
|
||||||
<v6Lto>2</v6Lto>
|
|
||||||
<v6WtE>2</v6WtE>
|
|
||||||
<v6Rtti>2</v6Rtti>
|
|
||||||
<VariousControls>
|
|
||||||
<MiscControls></MiscControls>
|
|
||||||
<Define></Define>
|
|
||||||
<Undefine></Undefine>
|
|
||||||
<IncludePath></IncludePath>
|
|
||||||
</VariousControls>
|
|
||||||
</Cads>
|
|
||||||
</FileArmAds>
|
|
||||||
</FileOption>
|
|
||||||
</File>
|
</File>
|
||||||
<File>
|
<File>
|
||||||
<FileName>perf_counter.h</FileName>
|
<FileName>perf_counter.h</FileName>
|
||||||
@ -469,49 +418,6 @@
|
|||||||
<FileName>systick_wrapper_ual.s</FileName>
|
<FileName>systick_wrapper_ual.s</FileName>
|
||||||
<FileType>2</FileType>
|
<FileType>2</FileType>
|
||||||
<FilePath>..\systick_wrapper_ual.s</FilePath>
|
<FilePath>..\systick_wrapper_ual.s</FilePath>
|
||||||
<FileOption>
|
|
||||||
<CommonProperty>
|
|
||||||
<UseCPPCompiler>2</UseCPPCompiler>
|
|
||||||
<RVCTCodeConst>0</RVCTCodeConst>
|
|
||||||
<RVCTZI>0</RVCTZI>
|
|
||||||
<RVCTOtherData>0</RVCTOtherData>
|
|
||||||
<ModuleSelection>0</ModuleSelection>
|
|
||||||
<IncludeInBuild>0</IncludeInBuild>
|
|
||||||
<AlwaysBuild>2</AlwaysBuild>
|
|
||||||
<GenerateAssemblyFile>2</GenerateAssemblyFile>
|
|
||||||
<AssembleAssemblyFile>2</AssembleAssemblyFile>
|
|
||||||
<PublicsOnly>2</PublicsOnly>
|
|
||||||
<StopOnExitCode>11</StopOnExitCode>
|
|
||||||
<CustomArgument></CustomArgument>
|
|
||||||
<IncludeLibraryModules></IncludeLibraryModules>
|
|
||||||
<ComprImg>1</ComprImg>
|
|
||||||
</CommonProperty>
|
|
||||||
<FileArmAds>
|
|
||||||
<Aads>
|
|
||||||
<interw>2</interw>
|
|
||||||
<Ropi>2</Ropi>
|
|
||||||
<Rwpi>2</Rwpi>
|
|
||||||
<thumb>2</thumb>
|
|
||||||
<SplitLS>2</SplitLS>
|
|
||||||
<SwStkChk>2</SwStkChk>
|
|
||||||
<NoWarn>2</NoWarn>
|
|
||||||
<uSurpInc>2</uSurpInc>
|
|
||||||
<useXO>2</useXO>
|
|
||||||
<ClangAsOpt>0</ClangAsOpt>
|
|
||||||
<VariousControls>
|
|
||||||
<MiscControls></MiscControls>
|
|
||||||
<Define></Define>
|
|
||||||
<Undefine></Undefine>
|
|
||||||
<IncludePath></IncludePath>
|
|
||||||
</VariousControls>
|
|
||||||
</Aads>
|
|
||||||
</FileArmAds>
|
|
||||||
</FileOption>
|
|
||||||
</File>
|
|
||||||
<File>
|
|
||||||
<FileName>perf_counter.lib</FileName>
|
|
||||||
<FileType>4</FileType>
|
|
||||||
<FilePath>..\lib\perf_counter.lib</FilePath>
|
|
||||||
</File>
|
</File>
|
||||||
<File>
|
<File>
|
||||||
<FileName>perfc_port_default.c</FileName>
|
<FileName>perfc_port_default.c</FileName>
|
||||||
@ -1021,30 +927,6 @@
|
|||||||
<FileType>2</FileType>
|
<FileType>2</FileType>
|
||||||
<FilePath>..\systick_wrapper_ual.s</FilePath>
|
<FilePath>..\systick_wrapper_ual.s</FilePath>
|
||||||
</File>
|
</File>
|
||||||
<File>
|
|
||||||
<FileName>perf_counter.lib</FileName>
|
|
||||||
<FileType>4</FileType>
|
|
||||||
<FilePath>..\lib\perf_counter.lib</FilePath>
|
|
||||||
<FileOption>
|
|
||||||
<CommonProperty>
|
|
||||||
<UseCPPCompiler>2</UseCPPCompiler>
|
|
||||||
<RVCTCodeConst>0</RVCTCodeConst>
|
|
||||||
<RVCTZI>0</RVCTZI>
|
|
||||||
<RVCTOtherData>0</RVCTOtherData>
|
|
||||||
<ModuleSelection>0</ModuleSelection>
|
|
||||||
<IncludeInBuild>0</IncludeInBuild>
|
|
||||||
<AlwaysBuild>2</AlwaysBuild>
|
|
||||||
<GenerateAssemblyFile>2</GenerateAssemblyFile>
|
|
||||||
<AssembleAssemblyFile>2</AssembleAssemblyFile>
|
|
||||||
<PublicsOnly>2</PublicsOnly>
|
|
||||||
<StopOnExitCode>11</StopOnExitCode>
|
|
||||||
<CustomArgument></CustomArgument>
|
|
||||||
<IncludeLibraryModules></IncludeLibraryModules>
|
|
||||||
<ComprImg>1</ComprImg>
|
|
||||||
</CommonProperty>
|
|
||||||
<FileArmAds/>
|
|
||||||
</FileOption>
|
|
||||||
</File>
|
|
||||||
<File>
|
<File>
|
||||||
<FileName>perfc_port_default.c</FileName>
|
<FileName>perfc_port_default.c</FileName>
|
||||||
<FileType>1</FileType>
|
<FileType>1</FileType>
|
||||||
@ -1711,11 +1593,6 @@
|
|||||||
</FileArmAds>
|
</FileArmAds>
|
||||||
</FileOption>
|
</FileOption>
|
||||||
</File>
|
</File>
|
||||||
<File>
|
|
||||||
<FileName>perf_counter.lib</FileName>
|
|
||||||
<FileType>4</FileType>
|
|
||||||
<FilePath>..\lib\perf_counter.lib</FilePath>
|
|
||||||
</File>
|
|
||||||
<File>
|
<File>
|
||||||
<FileName>perfc_port_default.c</FileName>
|
<FileName>perfc_port_default.c</FileName>
|
||||||
<FileType>1</FileType>
|
<FileType>1</FileType>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user