# Get started

There are several ways to use SIMD in your C/C++ program. The most direct way is to embed SIMD assembly in your code, which is apparently cumbersome and error-prone. You can also let the compiler automatically optimize your code with SIMD by using openMP (we will cover openMP later in this course). For example:

```c
#pragma omp simd
for(i=0;i<N;i++)
{
    C[i] = A[i] + B[i];
}
```

However, the code patterns that can be automatically detected and optimized by Compiler are limited.&#x20;

SIMD intrinsics are convenient if you want to manually optimize your code using SIMD without touching assembly. It is basically a library that wraps SIMD assembly as C functions. Let's re-write our vector addition example by SIMD intrinsics.

{% code title="add\_simd.c" %}

```c
#include <xmmintrin.h> //header file for sse
#include <stdio.h>

void add_simd(float a[4], float b[4], float result[4])
{
	__m128 v1 = _mm_load_ps(a); // load float[4] as __m128 vector
	__m128 v2 = _mm_load_ps(b);
	__m128 v3 = _mm_add_ps(v1, v2); // add them up
	_mm_store_ps(result, v3); // store the result to float[4]
}

int main()
{
	float a[4] = {1, 2, 3, 4};
	float b[4] = {2, 3, 4, 5};
	float r[4];
	add_simd(a, b, r);
	printf("%f %f %f %f\n", r[0], r[1], r[2], r[3]);
}
```

{% endcode %}

***Notice** that before using SIMD intrinsics, you have to include a header file that contains the intrinsic you want. To find out which header file is required, you can refer to* [*Intel Intrinsic Guide*](https://software.intel.com/sites/landingpage/IntrinsicsGuide/)*. For example, `xmmintrin.h` is required for `__mm_add_ps`:*

![](https://2267274569-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LoF4fSjDhFLH6o9i9dX%2F-LoGT_IXLwdBSWMAjaTP%2F-LoGqNMgdRM7farT0sfZ%2Fimage.png?alt=media\&token=296f08ad-39f7-44b4-8d92-254cae33c531)

Before we explain the details of the code, let's compile and run the program first. To compile the above code with SSE enabled, run the following code:

```bash
gcc add_simd.c -o add_simd -msse
```

***Notice** that we should add an additional flag "-m\[CPUID Flag]"("-msse" in the above code snippet) when compiling your code with GCC Compiler. This flag is used to enable SSE instructions. Different instructions need different flags, you can refer to* [*Intel Intrinsic Guide*](https://software.intel.com/sites/landingpage/IntrinsicsGuide/) *to find the corresponding flag. For example:*

![](https://2267274569-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LoF4fSjDhFLH6o9i9dX%2F-LoGT_IXLwdBSWMAjaTP%2F-LoGv1d8X7jqpiJYEzPf%2Fimage.png?alt=media\&token=f0014e64-831f-4879-afb4-9aaf7f6d9d21)

Run the compiled executable, you can see the result is as expected:

![](https://2267274569-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LoF4fSjDhFLH6o9i9dX%2F-LoGT_IXLwdBSWMAjaTP%2F-LoGwJxH55zh6s_lBt-d%2Fimage.png?alt=media\&token=11a20aee-0633-4836-a9da-567e2cb5a670)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://eric-lo.gitbook.io/lab-1-simd/simd-in-c-c++/untitled.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
