UME::SIMD Tutorial 2: Calculations

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:

horizontal_vertical_vectorization

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.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s