テストステ論

高テス協会会長が, テストステロンに関する情報をお届けします.

likely/unlikely and readability

GCC and other major C compilers have a extension to give hints for compiler's branch prediction. This is called likely/unlikely.

Regarding the readability, it's generally true that less comments is virtue. When I was in the former company, VA LINUX, a veteran programmer said that comments is harmful because it bloats up the codes. I agree and it's a fact that code lines is strongly related to bugs in it.

In storage softwares, such computational efficiency matters less than the I/O optimization but I often like to add these macros as annotations that clarify fast-path and slow-path. I will show you examples from dm-writeboost.

mb = ht_lookup(wb, head, &key);
if (unlikely(mb)) {
    mutex_unlock(&wb->io_lock);
    return;
}

This is a typical pattern that combines unlikey and fast return. fast return is a good technique in C programing to cut off the minor possibilities. Generally, code should be straight. So other minor things should be eliminated quickly so readers can go straight through the main path. From this code, it's clear to see that mb is unlikely to be found from the result of ht_lookup. We don't need comments at all.

if (likely(io_fullsize(bio))) {
    mb->dirtiness.data_bits = 255;
} else {
    u8 i;
    u8 acc_bits = 0;
    for (i = io_offset(bio); i < (io_offset(bio) + bio_sectors(bio)); i++)
        acc_bits += (1 << i);

    mb->dirtiness.data_bits |= acc_bits;
}

Another example uses likely on the other hand. This code clearly shows that bio is likely to be full-sized (4KB) and we can give it a fast-path in this case. This is an another pattern of likely/fast-path combination.

Summary

likely/unlikely macros can be also used to improve readability of your code. These are typically two pattens:

  1. unlikely and fast-return
  2. likely and fast-path

By the way, I don't like MISRA-C coding rule because it prohibits fast-return. Really harmful.