2
\$\begingroup\$

I need to create a commandword to be send to hardware and I'd like to make is as efficient as possible (without going to Assembler or similar). The command is 16Bit long and has to be passed as an array of two bytes to the hardware interfacing library I use (wiringpi). The first four Bit are configuration Bits and the other 12 are the actual command.

My code currently looks like this:

// global variables
short prefix_A = 3 << (4+8);
short prefix_B = 11 << (4+8);
unsigned char dac_cmd[2];
short cmd;

// not thread safe but that's ok in this application
void send_cmd(bool A, short new_cmd){
  assert( new_cmd < 4096);
  cmd = (A?prefix_A:prefix_B) | new_cmd;
  dac_cmd[0] = cmd >> 8;
  dac_cmd[1] = cmd & (255);
  wiringPiSPIDataRW(0, dac_cmd, 2);
}

I especially don't like the additional copy from the short (cmd) to the uchar[2] (dac_cmd).

\$\endgroup\$
4
\$\begingroup\$
  1. Well, there's no need to copy the short into an array of (unsigned) char:
    Treating any type as an array of (optionally signed/unsigned) char is an explicit exception from the strict-aliasing-rule.
    (I assume your targets byte-order is big-endian for that. Or you will need to byte-swap it first.)

  2. Unless prefix_A and/or prefix_B should ever be dynamically changed, mark them as const so you don't change them accidentally, and the compiler knows they cannot change so it will optimize accordingly.

So it becomes:

// constants
const short prefix_A = 3 << (4+8);
const short prefix_B = 11 << (4+8);

void send_cmd(bool A, short cmd){
    assert( cmd < 4096);
    cmd |= A ? prefix_A : prefix_B;
    cmd = htons(cmd); // byte-swap if little-endian
    wiringPiSPIDataRW(0, (unsigned char*)&cmd, 2);
}
\$\endgroup\$
  • 1
    \$\begingroup\$ Thanks! That's what I was looking for. And the htons was needed. \$\endgroup\$ – FooBar Oct 17 '15 at 14:53
  • \$\begingroup\$ Just be aware that short may not always be 16 bits. Shifting each byte into a two byte array is "safer". I'd only do this if you see a performance problem. \$\endgroup\$ – D.Shawley Oct 18 '15 at 2:41
  • \$\begingroup\$ @D.Shawley: Well, sure there are DSPs and really old machines where short and/or char may have more bits. But I guess we are safe enough this time. Even if in general you are quite right. \$\endgroup\$ – Deduplicator Oct 18 '15 at 3:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.