c9, Performance Monitor Control Register

news/2025/3/19 23:34:37/

http://liuluheng.github.io/wiki/public_html/Embedded-System/Cortex-A8/Performance%20Monitor%20Control%20Register.html

目录

enable the perfromance counter

c9, User Enable Register

c9, Interrupt Enable Clear Register

access the cycle-counter from the user-mode

c9, Cycle Count Register

c9, Performance Monitor Control Register

c9, Count Enable Set Register

c9, Overflow Flag Status Register

How to use it

Footnotes:


The purpose of the Performance MoNitor Control (PMNC) Register is to control the operation of the four Performance Monitor Count Registers, and the Cycle Counter Register:1

The PMNC Register is:

  • a read/write register common to Secure and Nonsecure states
  • accessible as determined by c9, User Enable Register.2

enable the perfromance counter

Accessing the performance counters isn't difficult, but you have to enable them from kernel-mode. By default the counters are disabled.

In a nutshell you have to execute the following two lines inside the kernel. Either as a loadable module or just adding the two lines somewhere in the board-init will do:

/* enable user-mode access to the performance counter*/asm ("MCR p15, 0, %0, C9, C14, 0\n\t" :: "r"(1)); /* disable counter overflow interrupts (just in case)*/asm ("MCR p15, 0, %0, C9, C14, 2\n\t" :: "r"(0x8000000f));

Once you did this the cycle counter will start incrementing for each cycle. Overflows of the register will go unnoticed and don't cause any problems (except they might mess up your measurements).

c9, User Enable Register

asm ("MCR p15, 0, %0, C9, C14, 0\n\t" :: "r"(1));

The purpose of the USER ENable (USEREN) Register is to enable User mode to have access to the Performance Monitor Registers.3

To access the USEREN Register, read or write CP15 with:

MRC p15, 0, <Rd>, c9, c14, 0 ; Read USEREN Register

MCR p15, 0, <Rd>, c9, c14, 0 ; Write USEREN Register

c9, Interrupt Enable Clear Register

asm ("MCR p15, 0, %0, C9, C14, 2\n\t" :: "r"(0x8000000f));

The purpose of the INTerrupt ENable Clear (INTENC) Register is to determine if any of the Performance Monitor Count Registers, PMCNT0-PMCNT3 and CCNT, generate an interrupt on overflow.4

To access the INTENC Register, read or write CP15 with:

MRC p15, 0, <Rd>, c9, c14, 2 ; Read INTENC Register

MCR p15, 0, <Rd>, c9, c14, 2 ; Write INTENC Register

access the cycle-counter from the user-mode

Now you want to access the cycle-counter from the user-mode:

We start with a function that reads the register:

static inline unsigned int get_cyclecount (void)
{unsigned int value;// Read CCNT Registerasm volatile ("MRC p15, 0, %0, c9, c13, 0\t\n": "=r"(value));  return value;
}

And you most likely want to reset and set the divider as well:

static inline void init_perfcounters (int32_t do_reset, int32_t enable_divider)
{// in general enable all counters (including cycle counter)int32_t value = 1;// peform reset:  if (do_reset){value |= 2;     // reset all counters to zero.value |= 4;     // reset cycle counter to zero.} if (enable_divider)value |= 8;     // enable "by 64" divider for CCNT.value |= 16;// program the performance-counter control-register:asm volatile ("MCR p15, 0, %0, c9, c12, 0\t\n" :: "r"(value));  // enable all counters:  asm volatile ("MCR p15, 0, %0, c9, c12, 1\t\n" :: "r"(0x8000000f));  // clear overflows:asm volatile ("MCR p15, 0, %0, c9, c12, 3\t\n" :: "r"(0x8000000f));
}

do_reset will set the cycle-counter to zero. Easy as that.

enable_diver will enable the 1/64 cycle divider. Without this flag set you'll be measuring each cycle. With it enabled the counter gets increased for every 64 cycles. This is useful if you want to measure long times that would otherwise cause the counter to overflow.

c9, Cycle Count Register

asm volatile ("MRC p15, 0, %0, c9, c13, 0\t\n": "=r"(value));

The purpose of the Cycle CouNT (CCNT) Register is to count the number of clock cycles since the register was reset. 5

To access the CCNT Register, read or write CP15 with:

MRC p15, 0, <Rd>, c9, c13, 0 ; Read CCNT Register MCR p15, 0, <Rd>, c9, c13, 0 ; Write CCNT Register

c9, Performance Monitor Control Register

asm volatile ("MCR p15, 0, %0, c9, c12, 0\t\n" :: "r"(value));

To access the PMNC Register, read or write CP15 with:1

MRC p15, 0, <Rd>, c9, c12, 0 ; Read PMNC Register

MCR p15, 0, <Rd>, c9, c12, 0 ; Write PMNC Register

c9, Count Enable Set Register

asm volatile ("MCR p15, 0, %0, c9, c12, 1\t\n" :: "r"(0x8000000f)); The purpose of the CouNT ENable Set (CNTENS) Register is to enable or disable any of the Performance Monitor Count Registers.

When reading this register, any enable that reads as 0 indicates the counter is disabled. Any enable that reads as 1 indicates the counter is enabled.

When writing this register, any enable written with a value of 0 is ignored, that is, not updated. Any enable written with a value of 1 indicates the counter is enabled.6

To access the CNTENS Register, read or write CP15 with:

MRC p15, 0, <Rd>, c9, c12, 1 ; Read CNTENS Register

MCR p15, 0, <Rd>, c9, c12, 1 ; Write CNTENS Register

c9, Overflow Flag Status Register

asm volatile ("MCR p15, 0, %0, c9, c12, 3\t\n" :: "r"(0x8000000f)); The purpose of the Overflow Flag Status (FLAG) Register is to enable or disable any of the performance monitor counters producing an overflow flag.7

To access the FLAG Register, read or write CP15 with:

MRC p15, 0, <Rd>, c9, c12, 3 ; Read FLAG Register

MCR p15, 0, <Rd>, c9, c12, 3 ; Write FLAG Register

How to use it

// init counters:init_perfcounters (1, 0); // measure the counting overhead:unsigned int overhead = get_cyclecount();overhead = get_cyclecount() - overhead;    unsigned int t = get_cyclecount();// do some stuff here..call_my_function();t = get_cyclecount() - t;printf ("function took exactly %d cycles (including function call)", t - overhead);

Should work on all Cortex-A8 CPUs.

some notes:

Using these counters you'll measure the exact time between the two calls to get_cyclecount() including everything spent in other processes or in the kernel. There is no way to restrict the measurement to your process or a single thread.

Also calling get_cyclecount() isn't free. It will compile to a single asm-instruction, but moves from the co-processor will stall the entire ARM pipeline. The overhead is quite high and can skew your measurement. Fortunately the overhead is also fixed, so you can measure it and subtract it from your timings.

In this example I did that for every measurement. Don't do this in practice. An interrupt will sooner or later occur between the two calls and skew your measurements even further. I suggest that you measure the overhead a couple of times on an idle system, ignore all outsiders and use a fixed constant instead.8

Footnotes:

c9, Performance Monitor Control Register

Cortex-A8 Technical Reference Manua

c9, User Enable Register

c9, Interrupt Enable Clear Register

c9, Cycle Count Register

c9, Count Enable Set Register

c9, Overflow Flag Status Register

stackoverflow

Author: Shi Shougang

Created: 2015-03-05 Thu 23:20

Emacs 24.3.1 (Org mode 8.2.10)

Validate


http://www.ppmy.cn/news/341396.html

相关文章

【Linux】C9

目录 设置权限umask 设置默认权限 umask永久生效 访问控制列表&#xff08;acl&#xff09; 查看用户acl权限&#xff1a;getfacl 文件路径 设置用户alc权限&#xff1a;setfacl -m u:用户名:权限 文件路径 删除acl权限&#xff08;文件上所有acl权限&#xff09;&…

ps复制图层警告 (不能从选区建立新图层,因为所选区域是空的。)解决方法

有时我们选完选区 按 CtrlJ 复制图层 会出现这种情况 问题出在你当前选的图层 因为 我选择的这块选区在第二个图层上 但很明显 选择的是一大个图层 简单说 你操作的选区必须在你当前选择的图层上才行 也就是 我现在要将选择区换成第二个图层才行 再按 CtrlJ 图层就出来了

JAVA中PRIORITYQUEUE详解

ava中PriorityQueue通过二叉小顶堆实现&#xff0c;可以用一棵完全二叉树表示。本文从Queue接口函数出发&#xff0c;结合生动的图解&#xff0c;深入浅出地分析PriorityQueue每个操作的具体过程和时间复杂度&#xff0c;将让读者建立对PriorityQueue建立清晰而深入的认识。 总…

混沌演练状态下,如何降低应用的MTTR(平均恢复时间)| 京东云技术团队

在企业业务领域&#xff0c;锦礼是针对福利、营销、激励等员工采购场景的一站式解决方案&#xff0c;包含面向员工、会员等弹性激励SAAS平台。由于其直接面向公司全体员工&#xff0c;其服务的高可用尤其重要&#xff0c;本文将介绍锦礼商城大促前夕&#xff0c;通过混沌工程实…

对讲机装配与调试

四&#xff0e;装配与调试 对讲机的装配方法与一般无线电整机的装配方法差不多&#xff0c;应当注意的是&#xff0c;元器件的引脚应尽可能的短&#xff0c;以便紧贴印刷板&#xff0c;引至天线座的连线也应尽可能的短&#xff0c;否则输出功率也会明显下降。如果输出端离天线座…

java公网对讲_【对讲机的那点事】选择公网对讲机你必须要知道使用的网络信号!...

公网对讲机对于广大的用户来说已经不再陌生&#xff0c;公网对讲机的构成主要由硬件部分、IP网络运营平台、运营商提供的流量卡三大要素组成。利用移动通信的数据通道&#xff0c;将话音数字化&#xff0c;压缩&#xff0c;然后经现有的公众移动数据网络发送出去&#xff0c;形…

北京某金融公司面试题,精选10道讲解!

你好&#xff0c;我是田哥 面试造火箭工作拧螺丝&#xff0c;最近一位朋友在面试中被问到各种各样的分布式微服务的面试题&#xff0c;也回答上来了。可是&#xff0c;等正式入职后&#xff0c;发现这家公司居然全部是使用单体项目&#xff0c;完全没有分布式微服务的东东&…

解决Antd Tree组件,二次点击时不取消选中,保持高亮

一、问题概述 ant design 提供的 Tree树组件 支持点击高亮树节点&#xff0c;再次点击取消高亮。 默认效果如下&#xff1a; 然而大多数业务场景下&#xff0c;我们希望多次点击同一个节点不会取消他的选中效果。 二、解决方案 监听onSelect时间&#xff0c;并使用select…