Skip to content

Commit

Permalink
update document
Browse files Browse the repository at this point in the history
  • Loading branch information
GorgonMeducer committed Feb 28, 2024
1 parent 7f4293f commit 0591cdb
Show file tree
Hide file tree
Showing 4 changed files with 125 additions and 146 deletions.
134 changes: 124 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -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:
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
### 1.2 Timestamp
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.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()`.
Expand Down Expand Up @@ -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:

Expand All @@ -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()`.
Expand All @@ -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:
Expand All @@ -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:
Expand Down
Binary file added documents/pictures/__cpu_perf__output.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 1 addition & 13 deletions example/example.uvoptx
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand All @@ -791,7 +779,7 @@
</File>
<File>
<GroupNumber>2</GroupNumber>
<FileNumber>9</FileNumber>
<FileNumber>8</FileNumber>
<FileType>5</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
Expand Down
123 changes: 0 additions & 123 deletions example/example.uvprojx
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand All @@ -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>
Expand Down Expand Up @@ -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>
Expand Down Expand Up @@ -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>
Expand Down

0 comments on commit 0591cdb

Please sign in to comment.