I'm working with STM32 board which a microcontroller is embedded. This MCU seems to work within 72MHz max. Now if I make a C code, does that mean each simple instructions would be done within 72MHz? What I mean by simple instruction is adding 1 to an integer variable for instance. Each 1/72MHz that variable will get +1?
It depends on the microcontroller. Few processors, microcontroller or otherwise, can do all their operations in a single clock cycle; most of them require different numbers of clock cycles for different instructions. It's not C instructions that matter here, either--it's assembly (or machine code) instructions, the native instructions of the processor. One C instruction can expand out into dozens of assembly instructions, and some of those may take tens of clock cycles to complete.
Typically, your most basic instructions are the fastest. Adding two registers, incrementing or decrementing a register, performing logic operations, that sort of thing. Instructions that access memory are slower; loading data from memory into a register, storing a register into memory, and arithmetic operations involving memory data all usually take an extra couple clock cycles. Program flow control instructions, like JMP, are also typically a few cycles slower, and they usually flush the pipeline in pipelined processors.
The slowest instruction on processors that support it is usually division. I've seen architectures where division takes over a hundred clock cycles while addition takes just two or three. Division is complicated.
The STM32 is based on the ARM Cortex-M4 processor architecture, so this instruction set reference can be used to investigate how many cycles each instruction takes. Note that some instructions take variable time; division, for instance, takes between 2 and 12 clock cycles depending on the numbers being divided.
The cortex-M4 is fortunately simple for an ARM processor; more advanced ARM processors, like many modern processors, have very complex dependency chains that determine how long any given instruction takes.
The clock frequency means how fast you can run the system clock. Each assembler instruction takes a number of clock cycles to carried out, as documented in the assembler manual. And each C expression will in turn boil down to multiple assembler instructions.
Here is an example, where I made everything
volatile and disabled optimization, just to ensure that directly corresponding assembler gets generated:
volatile int a=1, b=1; volatile int c = a + b;
Compiling this with gcc for ARM32 gives me roughly something like this for
c = a + b:
ldr r2, [r7, #12] ldr r3, [r7, #8] add r3, r3, r2 str r3, [r7, #4] movs r3, #0
Each of these instructions take a certain amount of clock ticks. So we'll have to look up each and every instruction and count the ticks.
But lets for simplicity's sake imagine an example where they all take 3 clock ticks:
- There is 5 instructions, 5x3 = 15.
t=1/fso at 72MHz each clock tick takes 13.88ns.
- 15 * 13.88*10^-9 and we end up with 208.33ns to execute the code.
In reality this is much more complex, in particular there might be timing overhead when loading code into registers from RAM or flash. To counter that, CPUs implement things like pipelining, which means that it starts to load several instructions at once. From Cortex M4, simpler forms of branch prediction might also be used. Beyond M4, data and/or instruction cache memories that act as a fast access buffer between the CPU and the slower memories.