MCKL
Monte Carlo Kernel Library
increment_sse2_64.hpp
Go to the documentation of this file.
1 //============================================================================
2 // MCKL/include/mckl/random/internal/increment_sse2_64.hpp
3 //----------------------------------------------------------------------------
4 // MCKL: Monte Carlo Kernel Library
5 //----------------------------------------------------------------------------
6 // Copyright (c) 2013-2018, Yan Zhou
7 // All rights reserved.
8 //
9 // Redistribution and use in source and binary forms, with or without
10 // modification, are permitted provided that the following conditions are met:
11 //
12 // Redistributions of source code must retain the above copyright notice,
13 // this list of conditions and the following disclaimer.
14 //
15 // Redistributions in binary form must reproduce the above copyright notice,
16 // this list of conditions and the following disclaimer in the documentation
17 // and/or other materials provided with the distribution.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS
20 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 // POSSIBILITY OF SUCH DAMAGE.
30 //============================================================================
31 
32 #ifndef MCKL_RANDOM_INTERNAL_INCREMENT_SSE2_64_HPP
33 #define MCKL_RANDOM_INTERNAL_INCREMENT_SSE2_64_HPP
34 
39 
40 MCKL_PUSH_GCC_WARNING("-Wignored-attributes")
41 
42 namespace mckl {
43 
44 namespace internal {
45 
46 template <typename T, std::size_t K, std::size_t S>
47 inline void increment_si128(
48  std::array<T, K> &ctr, std::array<__m128i, S> &s, std::false_type)
49 {
50  constexpr T blocks = (sizeof(__m128i) * S) / (sizeof(T) * K);
51 
52  alignas(MCKL_ALIGNMENT) std::array<std::array<T, K>, blocks> ctr_block;
53  increment(ctr, ctr_block);
54  std::memcpy(s.data(), ctr_block.data(), sizeof(__m128i) * S);
55 }
56 
57 template <typename T, std::size_t K, std::size_t S>
58 inline void increment_si128(
59  std::array<T, K> &ctr, std::array<__m128i, S> &s, std::true_type)
60 {
61  constexpr T blocks = (sizeof(__m128i) * S) / (sizeof(T) * K);
62 
63  if (std::get<0>(ctr) < std::numeric_limits<T>::max() - blocks) {
65  std::get<0>(ctr) += blocks;
66  } else {
67  increment_si128(ctr, s, std::false_type());
68  }
69 }
70 
71 template <typename T, std::size_t K, std::size_t S>
72 MCKL_INLINE inline void increment_si128(
73  std::array<T, K> &ctr, std::array<__m128i, S> &s)
74 {
75  constexpr bool direct = S == 4 || S == 8 || S == 16;
76  constexpr bool bits = std::numeric_limits<T>::digits == 64;
77 
79  ctr, s, std::integral_constant<bool, (direct && bits)>());
80 }
81 
82 } // namespace internal
83 
84 } // namespace mckl
85 
87 
88 #endif // MCKL_RANDOM_INTERNAL_INCREMENT_SSE2_64_HPP
#define MCKL_PUSH_GCC_WARNING(warning)
Definition: compiler.h:78
void increment_si128(std::array< T, K > &ctr, std::array< __m128i, S > &s, std::true_type)
void increment(std::array< T, K > &ctr, std::integral_constant< T, NSkip >)
Increment a counter by given steps.
Definition: mcmc.hpp:40
#define MCKL_ALIGNMENT
The default alignment for scalar type.
Definition: config.h:187
#define MCKL_INLINE
Definition: clang.h:147
#define MCKL_POP_GCC_WARNING
Definition: compiler.h:79