## Horizontal vs. Vertical vectorization

Once the SIMD vectors are initialized with data, they will be operated upon. When operating on vectors, we need to distinguish two directions of operations: horizontal and vertical. The easiest way to understand the difference is by looking at a following diagram:

In the diagram we can distinguish two directions relating to either data orientation or instruction orientation. Vertical vectorization will be a process of operating in an *elementwise* manner on elements of each vector. For the first **ADD** operation, the result will be, as if we executed following list of operations:

c0=a0+b0; c1=a1+b1; c2=a2+b2; c3=a3+b3;

Mind that vertical operations can also operate on a single vector, the same way as **SQRT** operation:

f0=sqrt(e0); f1=sqrt(e1); f2=sqrt(e2); f3=sqrt(e3);

A horizontal operation, or a * reduction *, is one involving applying an operator between elements of a vector. From the example above this would be **HADD** operation, which would have the same meaning as:

x=f0+f1+f2+f3;

Another way of remembering the distinction between horizontal and vertical operations is as follows: vertical operation always returns a vector, while horizontal always returns a scalar. By convention names of hoirzontal operations are prefixed with **H-** letter, such as in **HADD**.

## Invoking operations in UME::SIMD

When operating on vectors simply use overloaded operators, as if you were working with scalars:

UME::SIMD::SIMDVec<float, 4> a, b, c, d, e, f; ... c = a + b; e = c * d;

For additional operations, the ones that don’t have an equivalent C++ operator, you can either use a special namespace **UME::SIMD::FUNCTIONS** or a **Member Function Interface** (**MFI**) invocation convention:

f = UME::SIMD::FUNCTIONS::sqrt(e); // or f = e.sqrt(); // MFI call

MFI invocation convention is especially useful when using UME::SIMD as a code generation target, as it allows invoking every operation supported by the library in the same way. For regular development I advise using operators and functions as this will result in better code readability.

Invocation of a horizontal operation cannot be done using operator syntax, as the concept of reduction operation is not present in current C++ language. You have to therefor use either **FUNCTIONS** namespace or **MFI**:

float x = UME::SIMD::FUNCTIONS::hadd(f); // or float x = e.hadd(); // MFI call

Which syntax convention to use is up to you.