Hello, dear friend, you can consult us at any time if you have any questions, add WeChat: daixieit

Short guide to writing SIMD code


In this document we will be going over how to write simple SIMD code in C. As an example we  will see how to translate scalar code that adds two arrays together into SIMD code. We assume that the length of the arrays we are operating on is a multiple of 8.

Scalar code:

 

 

Step 1.

Include the library for using Intel Intrinsics for AVX512.

 

 

 

This is already included in the skeleton code for project 2.

 

 

Step 2.

Declare vectors for holding elements from a and b, and load integer data into them.

We will first declare two variables for holding 512 bits of integer from arrays a and b. We can     look at the following guide for using Intel Intrinsics (link) and determine that we need a __m512i data type in order to hold 512 bits of integer data. We declare two of these variables, and          increment our loop counter by 8 on each iteration as we are operating on 8 elements at a time.

 

 


 

In each iteration of the loop, we want to load elements from a and b and store them in the         variables we declared above. To do this we go to the Intel Intrinsics Guide (link) and look up the function that loads 512 bits of integer data from an address.

Typing something like “_mm512_load” in the search box gives a list of functions that might      satisfy our requirements. Among the functions we choose “_mm512_loadu_si512()” as it loads 512 bits of integer data from an address. (We cannot use _mm512_load_si512() /                    _mm512_load_epi64() as arrays a and b may not be aligned on a 512 bit boundary, and          _mm512_loadu_epi64() is deprecated and may not be declared in the library anymore.) We    then change our code to load elements of a and b at each iteration.

 

 

 

Note: For project 2, the arrays that contain the data will be aligned on 512 bit boundaries,       so use SIMD instructions for aligned data when operating on data from these arrays. Using unaligned instructions in this case may result in a drop in execution speed.

Step 4.

Add the two vectors together.

We now wish to add a_vec and b_vec using SIMD. Similarly to step 3, we go to the Intel         Intrinsics Guide and choose a function that adds two vectors of 8 64-bit integers. Again typing something like _mm512_add” gives a list of candidate functions, and we choose                    “_mm512_add_epi64” . We use this function to add a_vec and b_vec and store the result in a new __m512i variable.

 

 


Step 5.

Store the result of addition into c.

We now wish to write the result of addition into the correct location of array c. We look for a “store” function in the Intel Intrinsic Guide, which does the opposite operation as a load as it writes a vector to a memory address. We see that _mm512_storeu_si512() satisfies our      requirements, and use it to write 512 bits to c.

 

 

 

Step 6. (Optional)

The code above can be written into a single line as the following.