mirror of
https://github.com/GorgonMeducer/perf_counter.git
synced 2025-01-24 19:23:03 +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`.
|
||||
|
||||
### 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**.
|
||||
- Measure **RAW/True** cycles used for a data-process-path across multiple threads.
|
||||
- **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.
|
||||
- Enable a broader processor architecture support
|
||||
- **Support ALL Cortex-M processors**
|
||||
- SysTick
|
||||
- **[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**
|
||||
- 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
|
||||
|
||||
@ -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)
|
||||
|
||||
### 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()`.
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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()`.
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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:
|
||||
|
||||
|
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>
|
||||
<GroupNumber>2</GroupNumber>
|
||||
<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>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
@ -791,7 +779,7 @@
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>2</GroupNumber>
|
||||
<FileNumber>9</FileNumber>
|
||||
<FileNumber>8</FileNumber>
|
||||
<FileType>5</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
|
@ -408,57 +408,6 @@
|
||||
<FileName>perf_counter.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<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>
|
||||
<FileName>perf_counter.h</FileName>
|
||||
@ -469,49 +418,6 @@
|
||||
<FileName>systick_wrapper_ual.s</FileName>
|
||||
<FileType>2</FileType>
|
||||
<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>
|
||||
<FileName>perfc_port_default.c</FileName>
|
||||
@ -1021,30 +927,6 @@
|
||||
<FileType>2</FileType>
|
||||
<FilePath>..\systick_wrapper_ual.s</FilePath>
|
||||
</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>
|
||||
<FileName>perfc_port_default.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
@ -1711,11 +1593,6 @@
|
||||
</FileArmAds>
|
||||
</FileOption>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>perf_counter.lib</FileName>
|
||||
<FileType>4</FileType>
|
||||
<FilePath>..\lib\perf_counter.lib</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>perfc_port_default.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
|
Loading…
x
Reference in New Issue
Block a user