user7317: I'm working on an Arduino program but am getting bogged down on what is the 'correct' implementation. I understand that multiple versions may work, so for my needs the 'correct' version will be the fastest (i.e. executing in the fewest clock cycles)
I need to set three analog input pins on my Mega 2560 - let's call them PF2-0.

I could use pinMode() - but that performs some extra checks that I want to leave out.
I could use _BV() in the process, but that's another function call I wish to avoid.

So, using port manipulation, I can write:
DDRF = 0x07; //PF2, PF1, PF0 as input
PORTF = 0x07; // Disable pullups

This should configure my three pins as inputs - and reduce any extraneous function calls. This should even be faster than writing:
DDRF = (1 << PF2) | (1 << PF1) | (1 << PF0)

Is this the fastest implementation?
*To be honest, I'm not sure how to profile this to know for sure.

user7508: The standard Arduino way of doing this is to use pinMode(). It's not
fast, but it's easy to understand, especially for beginners. And it's
portable across architectures.
If you want to go fast, then you should skip the Arduino functions and
use port manipulation, and avr-libc. The standard avr-libc way of doing
what you want is:
DDRF = _BV(PF2)   // set PF2 as output
     | _BV(PF1)   // also PF1
     | _BV(PF0);  // and PF0

This compiles to two assembly instructions: one for loading a CPU
register with the constant, and the other to copy the register to the
DDRF IO port. Notice that you set the bits for the pins you want to set
as outputs, and you clear the bits for the inputs. By default, all the
pins start as inputs.
The _BV() here is not a function call: it's a macro that expands to
(1 << (x)). The way you write the expression to the right of the =
sign is irrelevant as long as it is recognised to be a compile-time
constant. If you want to see for yourself, you can disassemble the
generated binary with the command
avr-objdump -S -C my_prog.elf > my_prog.lst

You get an assembly listing interspersed with your source. Doing this on
the example above yields:
    DDRF = _BV(PF2)   // set PF2 as output
         | _BV(PF1)   // also PF1
         | _BV(PF0);  // and PF0
100:    87 e0           ldi r24, 0x07   ; 7
102:    80 bb           out 0x10, r24   ; 16

Here, the ldi instruction means “load immediate”, i.e. load a register
(r24) with a constant value (0x07). The “out” instruction copies that
register into port 0x10 (namely DDRF). Both are single cycle
instructions, so the whole sequence takes two CPU cycles.

7317: <p>I'm working on an Arduino program but am getting bogged down on what is the 'correct' implementation. I understand that multiple versions may work, so for my needs the 'correct' version will be the fastest (i.e. executing in the fewest clock cycles)</p>

<p>I need to set three analog input pins on my Mega 2560 - let's call them PF2-0.</p>

<ul>
<li>I could use pinMode() - but that performs some extra checks that I want to leave out.</li>
<li>I could use _BV() in the process, but that's another function call I wish to avoid.</li>
</ul>

<p>So, using port manipulation, I can write:</p>

<pre><code>DDRF = 0x07; //PF2, PF1, PF0 as input
PORTF = 0x07; // Disable pullups
</code></pre>

<p>This should configure my three pins as inputs - and reduce any extraneous function calls. This should even be faster than writing:</p>

<pre><code>DDRF = (1 &lt;&lt; PF2) | (1 &lt;&lt; PF1) | (1 &lt;&lt; PF0)
</code></pre>

<p>Is this the fastest implementation?</p>

<p>*To be honest, I'm not sure how to profile this to know for sure.</p>
 7508: <p>The standard Arduino way of doing this is to use <code>pinMode()</code>. It's not
fast, but it's easy to understand, especially for beginners. And it's
portable across architectures.</p>

<p>If you want to go fast, then you should skip the Arduino functions and
use port manipulation, and avr-libc. The standard avr-libc way of doing
what you want is:</p>

<pre class="lang-cpp prettyprint-override"><code>DDRF = _BV(PF2)   // set PF2 as output
     | _BV(PF1)   // also PF1
     | _BV(PF0);  // and PF0
</code></pre>

<p>This compiles to two assembly instructions: one for loading a CPU
register with the constant, and the other to copy the register to the
DDRF IO port. Notice that you set the bits for the pins you want to set
as <em>outputs</em>, and you clear the bits for the inputs. By default, all the
pins start as inputs.</p>

<p>The <code>_BV()</code> here is not a function call: it's a macro that expands to
<code>(1 &lt;&lt; (x))</code>. The way you write the expression to the right of the <code>=</code>
sign is irrelevant as long as it is recognised to be a compile-time
constant. If you want to see for yourself, you can disassemble the
generated binary with the command</p>

<pre><code>avr-objdump -S -C my_prog.elf &gt; my_prog.lst
</code></pre>

<p>You get an assembly listing interspersed with your source. Doing this on
the example above yields:</p>

<pre><code>    DDRF = _BV(PF2)   // set PF2 as output
         | _BV(PF1)   // also PF1
         | _BV(PF0);  // and PF0
100:    87 e0           ldi r24, 0x07   ; 7
102:    80 bb           out 0x10, r24   ; 16
</code></pre>

<p>Here, the <code>ldi</code> instruction means “load immediate”, i.e. load a register
(r24) with a constant value (0x07). The “out” instruction copies that
register into port 0x10 (namely DDRF). Both are single cycle
instructions, so the whole sequence takes two CPU cycles.</p>
