Skip to content

Commit

Permalink
Merge branch 'master' into solution-319
Browse files Browse the repository at this point in the history
  • Loading branch information
kris-jusiak authored Mar 9, 2023
2 parents 1518fa3 + ff7da75 commit 44a28cb
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 1 deletion.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

### Tips

* [[320]](https://github.com/QuantlabFinancial/cpp_tip_of_the_week/blob/master/tips/320.md) - Did you know about intrisincts to support SIMD (Single Instruction, Multiple Data) instructions?
* [[319]](https://github.com/QuantlabFinancial/cpp_tip_of_the_week/blob/master/tips/319.md) - Did you know that C++11 allows calling functions with reference-to-array parameters from an initializer list?
* [[318]](https://github.com/QuantlabFinancial/cpp_tip_of_the_week/blob/master/tips/318.md) - Did you know that `std::unique_ptr` can be constexpr in C++23?
* [[317]](https://github.com/QuantlabFinancial/cpp_tip_of_the_week/blob/master/tips/317.md) - Did you know that with C++20 you can pass concepts?
Expand Down
35 changes: 34 additions & 1 deletion tips/319.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,44 @@ consteval auto sum_n(const auto (&... x)[2])
> https://godbolt.org/z/1fxxz6KEv
```cpp
```
template <typename... Ts, int... Ns>
consteval auto sum_n(const Ts (&...x)[Ns]) {
return (... + std::ranges::fold_left(x, Ts{}, std::plus{}));
}
```
> https://godbolt.org/z/bKdz3EEr1
```
template <auto... Ns>
constexpr auto sum_n(auto (&&...values)[Ns]) {
auto sum = 0;
return ([&] {
for (auto value : values) {
sum += value;
}
}(), ..., sum);
}
```
> https://godbolt.org/z/x7jn47Geb
```cpp
template<auto N>
consteval auto sum_n(const auto (&...array)[N]) {
auto result = (std::accumulate(array, array + N, 0) + ...);
return result;
}
```

> https://godbolt.org/z/rGG7KM7qa
```cpp
template<class... Lists, int ...N>
consteval auto sum_n(const Lists (&...v)[N]) {
return (std::accumulate(v, v+N, 0) + ...);
}
```
> https://godbolt.org/z/9hYTe14ds
64 changes: 64 additions & 0 deletions tips/320.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<details open><summary>Info</summary><p>

* **Did you know about intrisincts to support SIMD (Single Instruction, Multiple Data) instructions?**

* https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html

</p></details><details open><summary>Example</summary><p>

```cpp
#include <immintrin.h>

int main() {
const std::vector a = {1, 2, 3, 4};
const std::vector b = {5, 6, 7, 8};

const auto va = _mm_loadu_si128((__m128i*)a.data());
const auto vb = _mm_loadu_si128((__m128i*)b.data());
const auto result = _mm_add_epi32(va, vb);

std::vector<int> v(a.size());
_mm_storeu_si128((__m128i*)v.data(), result);

assert((std::vector{1 + 5, 2 + 6, 3 + 7, 4 + 8} == v));
}
```

> https://godbolt.org/z/nz1hx76j7
</p></details><details open><summary>Puzzle</summary><p>

> **Can you implement a function which computes the dot product of the two arrays using SIMD instructions?**
```cpp
[[nodiscard]] constexpr auto dot_product(const auto& lhs, const auto& rhs); // TODO

int main() {
using namespace boost::ut;

"simd.dot_product empty"_test = [] {
const std::vector<float> a{};
const std::vector<float> b{};

expect(0_i == dot_product(a, b));
};

"simd.dot_product one"_test = [] {
const std::vector a = {1.f};
const std::vector b = {3.f};

expect(_i(1*3) == dot_product(a, b));
};

"simd.dot_product many"_test = [] {
const std::vector a = {1.f, 2.f, 3.f, 4.f};
const std::vector b = {5.f, 6.f, 7.f, 8.f};

expect(_i(1*5+2*6+3*7+4*8) == dot_product(a, b));
};
}
```
> https://godbolt.org/z/GnrEh1YM9
</p></details><details><summary>Solutions</summary><p>

0 comments on commit 44a28cb

Please sign in to comment.