Created
February 13, 2021 16:40
-
-
Save alexey-milovidov/137f89ecc908fffecac7660d4e08df01 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <cstddef> | |
#include <cstdint> | |
#include <vector> | |
#include <iostream> | |
#define ALWAYS_INLINE __attribute__((__always_inline__)) | |
namespace | |
{ | |
template <size_t dst_offset, size_t head_size, size_t... tail_sizes> | |
ALWAYS_INLINE void copyTemplateMultiple(const char * __restrict * __restrict src_bases, size_t src_index, char * __restrict dst_base) | |
{ | |
__builtin_memcpy(dst_base + dst_offset, src_bases[0] + src_index * head_size, head_size); | |
if constexpr (sizeof...(tail_sizes) > 0) | |
copyTemplateMultiple<dst_offset + head_size, tail_sizes...>(src_bases + 1, src_index, dst_base); | |
} | |
/*template <typename T, size_t shift, size_t head_size, size_t... tail_sizes> | |
ALWAYS_INLINE void pushMultiple(const char * __restrict * __restrict src_bases, size_t src_index, T & dst) | |
{ | |
dst += *reinterpret_cast<>(src_bases[0] + src_index * head_size) << shift; | |
if constexpr (sizeof...(tail_sizes) > 0) | |
pushMultiple<T, shift + head_size * 8, tail_sizes...>(src_bases + 1, src_index, dst); | |
}*/ | |
} | |
template <typename T, size_t... sizes> | |
ALWAYS_INLINE T packMultiple(const char * __restrict * __restrict src_bases, size_t src_index) | |
{ | |
T res{}; | |
copyTemplateMultiple<0, sizes...>(src_bases, src_index, reinterpret_cast<char *>(&res)); | |
return res; | |
} | |
/*template <typename T, size_t... sizes> | |
ALWAYS_INLINE T packMultiple(const char * __restrict * __restrict src_bases, size_t src_index) | |
{ | |
T res{}; | |
pushMultiple<T, 0, sizes...>(src_bases, src_index, res); | |
return res; | |
}*/ | |
template uint64_t packMultiple<uint64_t, 1,1,1,1,1,1,1,1>(const char * __restrict * __restrict src_bases, size_t src_index); | |
template uint64_t packMultiple<uint64_t, 2,1,1,1,1,1,1>(const char * __restrict * __restrict src_bases, size_t src_index); | |
template uint64_t packMultiple<uint64_t, 1,2,1,1,1,1,1>(const char * __restrict * __restrict src_bases, size_t src_index); | |
template uint64_t packMultiple<uint64_t, 1,1,2,1,1,1,1>(const char * __restrict * __restrict src_bases, size_t src_index); | |
template uint64_t packMultiple<uint64_t, 1,1,1,2,1,1,1>(const char * __restrict * __restrict src_bases, size_t src_index); | |
template uint64_t packMultiple<uint64_t, 1,1,1,1,2,1,1>(const char * __restrict * __restrict src_bases, size_t src_index); | |
template uint64_t packMultiple<uint64_t, 1,1,1,1,1,2,1>(const char * __restrict * __restrict src_bases, size_t src_index); | |
template uint64_t packMultiple<uint64_t, 1,1,1,1,1,1,2>(const char * __restrict * __restrict src_bases, size_t src_index); | |
template uint64_t packMultiple<uint64_t, 4,1,1,1,1>(const char * __restrict * __restrict src_bases, size_t src_index); | |
template uint64_t packMultiple<uint64_t, 1,4,1,1,1>(const char * __restrict * __restrict src_bases, size_t src_index); | |
template uint64_t packMultiple<uint64_t, 1,1,4,1,1>(const char * __restrict * __restrict src_bases, size_t src_index); | |
template uint64_t packMultiple<uint64_t, 1,1,1,4,1>(const char * __restrict * __restrict src_bases, size_t src_index); | |
template uint64_t packMultiple<uint64_t, 1,1,1,1,4>(const char * __restrict * __restrict src_bases, size_t src_index); | |
template uint64_t packMultiple<uint64_t, 4,2,1,1>(const char * __restrict * __restrict src_bases, size_t src_index); | |
template uint64_t packMultiple<uint64_t, 4,1,2,1>(const char * __restrict * __restrict src_bases, size_t src_index); | |
template uint64_t packMultiple<uint64_t, 4,1,1,2>(const char * __restrict * __restrict src_bases, size_t src_index); | |
template uint64_t packMultiple<uint64_t, 2,4,1,1>(const char * __restrict * __restrict src_bases, size_t src_index); | |
template uint64_t packMultiple<uint64_t, 1,4,2,1>(const char * __restrict * __restrict src_bases, size_t src_index); | |
template uint64_t packMultiple<uint64_t, 1,4,1,2>(const char * __restrict * __restrict src_bases, size_t src_index); | |
template uint64_t packMultiple<uint64_t, 2,1,4,1>(const char * __restrict * __restrict src_bases, size_t src_index); | |
template uint64_t packMultiple<uint64_t, 1,2,4,1>(const char * __restrict * __restrict src_bases, size_t src_index); | |
template uint64_t packMultiple<uint64_t, 1,1,4,2>(const char * __restrict * __restrict src_bases, size_t src_index); | |
template uint64_t packMultiple<uint64_t, 2,1,1,4>(const char * __restrict * __restrict src_bases, size_t src_index); | |
template uint64_t packMultiple<uint64_t, 1,2,1,4>(const char * __restrict * __restrict src_bases, size_t src_index); | |
template uint64_t packMultiple<uint64_t, 1,1,2,4>(const char * __restrict * __restrict src_bases, size_t src_index); | |
template uint64_t packMultiple<uint64_t, 4,2,2>(const char * __restrict * __restrict src_bases, size_t src_index); | |
template uint64_t packMultiple<uint64_t, 2,4,2>(const char * __restrict * __restrict src_bases, size_t src_index); | |
template uint64_t packMultiple<uint64_t, 2,2,4>(const char * __restrict * __restrict src_bases, size_t src_index); | |
template uint64_t packMultiple<uint64_t, 4,4>(const char * __restrict * __restrict src_bases, size_t src_index); | |
template uint64_t packMultiple<uint64_t, 8>(const char * __restrict * __restrict src_bases, size_t src_index); | |
int main(int, char **) | |
{ | |
size_t size = 100000000; | |
std::vector<uint8_t> a(size); | |
std::vector<uint32_t> b(size); | |
std::vector<uint16_t> c(size); | |
std::vector<uint8_t> d(size); | |
std::vector<const char *> src(4); | |
src[0] = reinterpret_cast<const char *>(a.data()); | |
src[1] = reinterpret_cast<const char *>(b.data()); | |
src[2] = reinterpret_cast<const char *>(c.data()); | |
src[3] = reinterpret_cast<const char *>(d.data()); | |
std::vector<uint64_t> res(size); | |
for (size_t i = 0; i < size; ++i) | |
{ | |
res[i] = packMultiple<uint64_t, sizeof(a[0]), sizeof(b[0]), sizeof(c[0]), sizeof(d[0])>(src.data(), i); | |
} | |
std::cerr << res[0] << '\n'; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment