Skip to content

Commit

Permalink
simd: add initial simd exploration code (wip)
Browse files Browse the repository at this point in the history
Signed-off-by: Daniel Bevenius <[email protected]>
  • Loading branch information
danbev committed May 14, 2024
1 parent 6ac6f64 commit 029120f
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 0 deletions.
1 change: 1 addition & 0 deletions fundamentals/simd/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
bin
17 changes: 17 additions & 0 deletions fundamentals/simd/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
CXX = g++
CXXFLAGS = -g -Wall -mavx2 -Wno-unused-variable

SRCDIR = src
BINDIR = bin

SOURCES := $(wildcard $(SRCDIR)/*.cpp)
TARGETS := $(patsubst $(SRCDIR)/%.cpp, %, $(SOURCES))

all: $(TARGETS)

$(TARGETS): % : $(SRCDIR)/%.cpp | bindir
$(CXX) $(CXXFLAGS) -o ${BINDIR}/$@ $<

bindir: bin
bin:
@mkdir -p $(BINDIR)
54 changes: 54 additions & 0 deletions fundamentals/simd/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
## Single Instruction, Multiple Data (SIMD)

### Introduction
TODO:

### Machine specific options/support
If you just try to compile a program using SIMD instructions, you may get the
following error message:
```console
$ make add
gcc -g -Wall -Wno-unused-variable -o bin/add src/add.cpp
src/add.cpp: In function ‘int main()’:
src/add.cpp:11:52: warning: AVX vector return without AVX enabled changes the ABI [-Wpsabi]
11 | __m256i a = _mm256_loadu_si256((__m256i*)array1);
| ^
In file included from /usr/lib/gcc/x86_64-linux-gnu/11/include/immintrin.h:43,
from src/add.cpp:1:
/usr/lib/gcc/x86_64-linux-gnu/11/include/avxintrin.h:933:1: error: inlining failed in call to ‘always_inline’ ‘void _mm256_storeu_si256(__m256i_u*, __m256i)’: target specific option mismatch
933 | _mm256_storeu_si256 (__m256i_u *__P, __m256i __A)
| ^~~~~~~~~~~~~~~~~~~
src/add.cpp:18:24: note: called from here
18 | _mm256_storeu_si256((__m256i*)result, c);
| ~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~
In file included from /usr/lib/gcc/x86_64-linux-gnu/11/include/immintrin.h:47,
from src/add.cpp:1:
/usr/lib/gcc/x86_64-linux-gnu/11/include/avx2intrin.h:119:1: error: inlining failed in call to ‘always_inline’ ‘__m256i _mm256_add_epi32(__m256i, __m256i)’: target specific option mismatch
119 | _mm256_add_epi32 (__m256i __A, __m256i __B)
| ^~~~~~~~~~~~~~~~
src/add.cpp:15:33: note: called from here
15 | __m256i c = _mm256_add_epi32(a, b); // _epi32 denotes 32-bit integer vectors
| ~~~~~~~~~~~~~~~~^~~~~~
In file included from /usr/lib/gcc/x86_64-linux-gnu/11/include/immintrin.h:43,
from src/add.cpp:1:
/usr/lib/gcc/x86_64-linux-gnu/11/include/avxintrin.h:927:1: error: inlining failed in call to ‘always_inline’ ‘__m256i _mm256_loadu_si256(const __m256i_u*)’: target specific option mismatch
927 | _mm256_loadu_si256 (__m256i_u const *__P)
| ^~~~~~~~~~~~~~~~~~
src/add.cpp:12:35: note: called from here
12 | __m256i b = _mm256_loadu_si256((__m256i*)array2);
| ~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~
In file included from /usr/lib/gcc/x86_64-linux-gnu/11/include/immintrin.h:43,
from src/add.cpp:1:
/usr/lib/gcc/x86_64-linux-gnu/11/include/avxintrin.h:927:1: error: inlining failed in call to ‘always_inline’ ‘__m256i _mm256_loadu_si256(const __m256i_u*)’: target specific option mismatch
927 | _mm256_loadu_si256 (__m256i_u const *__P)
| ^~~~~~~~~~~~~~~~~~
src/add.cpp:11:35: note: called from here
11 | __m256i a = _mm256_loadu_si256((__m256i*)array1);
| ~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~
make: *** [Makefile:13: add] Error 1
```
In this case we nee to add the 'm'achine specific option `avx2` flag to the
compilation command:
```console
$ g++ -g -Wall -mavx2 -Wno-unused-variable -o bin/add src/add.cpp
```
22 changes: 22 additions & 0 deletions fundamentals/simd/src/add.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#include <immintrin.h>
#include <iostream>

int main() {
int array1[8] = {1, 2, 3, 4, 5, 6, 7, 8};
int array2[8] = {8, 7, 6, 5, 4, 3, 2, 1};
int result[8] = {0};

__m256i a = _mm256_loadu_si256((__m256i*)array1);
__m256i b = _mm256_loadu_si256((__m256i*)array2);

__m256i c = _mm256_add_epi32(a, b); // _epi32 denotes 32-bit integer vectors

_mm256_storeu_si256((__m256i*)result, c);

for (int i = 0; i < 8; i++) {
std::cout << "result[" << i << "] = " << result[i] << std::endl;
}

return 0;
}

0 comments on commit 029120f

Please sign in to comment.