ContentsThe library

What Makes Code Fast

The Same Add, Eight Numbers at a Time, If You Can Convince the Compiler It Is Safe

Last timeWhich Limit You Are Against

A single instruction can add eight pairs of numbers at once. The hardware has had this for decades and the reason your loop is not using it is almost always one you can remove.

Several values in one register

A processor register normally holds one number. A wide register holds several

side by side, typically four, eight or sixteen depending on the hardware and

the size of the numbers, and the instruction set has versions of the ordinary

operations that act on all of them at once.

One instruction, eight additions. The cost is roughly the cost of a single

addition, because the hardware has eight adders sitting next to each other and

they all work at the same time.

FIG 1One iteration of a narrow loop and a wide one
stepwhat happensnarrow versionwide versionelements donewhat happened
1loadone number from a, one from beight from a, eight from b1 and 8The wide load takes about the same time as the narrow one, because both fetch from the same cache line and the line was going to arrive whole regardless.
2addone additionone instruction, eight additions1 and 8This is the whole trick. The eight lanes do not interact at all, so there is no coordination to pay for and the instruction costs about what one addition costs.
3storeone number to ceight numbers to c1 and 8Again one instruction either way. The store writes a full line, which is also what the hardware prefers.
4loopadvance by 1, repeat n timesadvance by 8, repeat n over 8 timesn and nThe same total work, with the loop running an eighth as many times, which also removes seven eighths of the loop condition and the index arithmetic.
4 steps
Three instructions per eight elements instead of three per element. The gain is not only the arithmetic: the loop overhead, the index increment and the condition all shrink by the same factor, which is often half of the measured improvement.

The constraint implied by the picture is that the lanes do not interact. Eight

independent additions is the natural shape. Anything where element three needs

the result from element two does not fit, which is the same dependency problem

from the second lesson wearing different clothes.

FIG 2Iterations after widening
iterations the widened loop performs
elements to process
values the wide register holds, the lane count
Clean only when the element count divides by the lane count. When it does not, the leftover elements are handled by a narrow loop afterwards, which is why short loops gain much less than the width suggests: a loop over eleven elements does one wide iteration and three narrow ones.

What it has to prove

Compilers perform this transformation automatically and have done for decades.

They do it only when they can prove it is safe, and the proof has four parts.

The iterations must be independent, so that performing eight at once gives the

same answer as performing them one after another. The memory regions involved

must not overlap, since writing eight results at once is wrong if some of those

locations are also inputs to the same group. The number of iterations must be

known, or at least checkable at run time, so the leftover can be handled. And

every iteration must do the same work, because eight lanes perform the same

instruction and cannot each take a different path.

Each of those is a real requirement rather than a conservatism. A loop that

violates any of them produces a different answer when widened.

The lesson stops here

2 more paragraphs to go

You have read the opening. The rest of the argument, the problems that check whether it landed, and the lines worth keeping at the end all come with a plan.

The first lesson of every course in the library reads the whole way through, free, so you can see exactly what the rest of them are.

See the planThe contents

This is the reading half

Starting the course gives you your own copy of it. Every idea on every page has problems standing under it, marked with a reason rather than a tick, and any sentence you do not believe can be opened and argued with. None of that can happen on a page nobody owns.

The contents

The rest of this course

  1. 01Two Loops Doing Exactly the Same Arithmetic, One of Them Fifty Times Slower
  2. 02A Hundred Additions in the Time of Four, Unless Each One Waits for the Lastopening only
  3. 03Sorting the Array First Makes the Loop Six Times Faster Without Changing What It Computesopening only
  4. 04Compute Both Answers and Throw One Away, Which Is Faster Than Deciding Which to Computeopening only
  5. 05One Number Tells You Which Half of the Toolbox to Openopening only
  6. 06The Same Add, Eight Numbers at a Time, If You Can Convince the Compiler It Is Safeyou are here
  7. 07Most of the Time Is Going Somewhere That Does Not Appear Anywhere in Your Sourceopening only
  8. 08The Fastest Possible Version of a Tenth of Your Program Buys You Eleven Per Centopening only

Read alongside