Skip to content

Instantly share code, notes, and snippets.

@alexey-milovidov
Created February 13, 2021 16:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alexey-milovidov/137f89ecc908fffecac7660d4e08df01 to your computer and use it in GitHub Desktop.
Save alexey-milovidov/137f89ecc908fffecac7660d4e08df01 to your computer and use it in GitHub Desktop.
#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