parent
a8dce41cc4
commit
7598a8d6b9
@ -1,71 +0,0 @@
|
|||||||
#ifndef _VECTOR_H
|
|
||||||
#define _VECTOR_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include <mmintrin.h>
|
|
||||||
#include <immintrin.h>
|
|
||||||
#include <tmmintrin.h>
|
|
||||||
#include <xmmintrin.h>
|
|
||||||
#include <emmintrin.h>
|
|
||||||
|
|
||||||
#define _VECTOR_SIZE 16
|
|
||||||
|
|
||||||
// Vector128 int 8
|
|
||||||
typedef uint8_t v8_u128n __attribute__((vector_size(_VECTOR_SIZE)));
|
|
||||||
typedef int8_t v8_i128n __attribute__((vector_size(_VECTOR_SIZE)));
|
|
||||||
|
|
||||||
// Vector128 int 16
|
|
||||||
typedef uint16_t v16_u128n __attribute__((vector_size(_VECTOR_SIZE)));
|
|
||||||
typedef int16_t v16_i128n __attribute__((vector_size(_VECTOR_SIZE)));
|
|
||||||
|
|
||||||
// Vector128 int 32
|
|
||||||
typedef uint32_t v32_u128n __attribute__((vector_size(_VECTOR_SIZE)));
|
|
||||||
typedef int32_t v32_i128n __attribute__((vector_size(_VECTOR_SIZE)));
|
|
||||||
|
|
||||||
// Vector128 int 64
|
|
||||||
typedef uint64_t v64_u128n __attribute__((vector_size(_VECTOR_SIZE)));
|
|
||||||
typedef int64_t v64_i128n __attribute__((vector_size(_VECTOR_SIZE)));
|
|
||||||
|
|
||||||
typedef union v128 {
|
|
||||||
// Intrinsics
|
|
||||||
__m128i mm; // long int
|
|
||||||
__m128d mmd; // double
|
|
||||||
__m128 mmf; // float //XXX: Should we have the halfs
|
|
||||||
|
|
||||||
// Vectorised integers
|
|
||||||
union {
|
|
||||||
v8_u128n u8;
|
|
||||||
v8_i128n i8;
|
|
||||||
|
|
||||||
v16_u128n u16;
|
|
||||||
v16_i128n i16;
|
|
||||||
|
|
||||||
v32_u128n u32;
|
|
||||||
v32_i128n i32;
|
|
||||||
|
|
||||||
v64_u128n u64;
|
|
||||||
v64_i128n i64;
|
|
||||||
} as;
|
|
||||||
|
|
||||||
// Native 128 bit integers
|
|
||||||
unsigned __int128 u128;
|
|
||||||
signed __int128 i128;
|
|
||||||
|
|
||||||
// Raw bytes
|
|
||||||
uint8_t bytes[_VECTOR_SIZE];
|
|
||||||
} v128_t;
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
static_assert(sizeof(union v128)==_VECTOR_SIZE, "invalid vector size");
|
|
||||||
static_assert(alignof(union v128)==alignof(__m128i), "invalid vector alignment");
|
|
||||||
#else
|
|
||||||
_Static_assert(sizeof(union v128)==_VECTOR_SIZE, "invalid vector size");
|
|
||||||
_Static_assert(_Alignof(union v128)==_Alignof(__m128i), "invalid vector alignment");
|
|
||||||
#endif
|
|
||||||
#endif /* _VECTOR_H */
|
|
@ -0,0 +1,24 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <input.h>
|
||||||
|
|
||||||
|
extern int part1(uint64_t* restrict);
|
||||||
|
extern int part2();
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
register int r=0;
|
||||||
|
#ifdef _PART1
|
||||||
|
uint64_t p1;
|
||||||
|
if( (r = part1(&p1)) ) return r;
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf("[1] >>> %lu\n", p1);
|
||||||
|
#else
|
||||||
|
printf("%lu\n", p1);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#ifdef _PART2
|
||||||
|
if( (r = part2()) ) return r;
|
||||||
|
#endif
|
||||||
|
return r;
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
#include <input.h>
|
||||||
|
|
||||||
|
__attribute__((pure))
|
||||||
|
uint64_t chk_pair(const struct ipair* restrict pair)
|
||||||
|
{
|
||||||
|
return pair->prev < pair->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
int part1(uint64_t* restrict _res)
|
||||||
|
{
|
||||||
|
uint64_t res = 0;
|
||||||
|
for(size_t i=0;i<INPUT_SIZE-1;i++)
|
||||||
|
{
|
||||||
|
res += chk_pair((const struct ipair*)(INPUT+i));
|
||||||
|
}
|
||||||
|
*_res = res;
|
||||||
|
return 0;
|
||||||
|
}
|
@ -1,69 +0,0 @@
|
|||||||
#include <assert.h>
|
|
||||||
|
|
||||||
|
|
||||||
#include <input.h>
|
|
||||||
#include <vector.h>
|
|
||||||
|
|
||||||
#include <tracem/ints.h>
|
|
||||||
|
|
||||||
_Static_assert(sizeof(input_t)*INPUT_VECTOR_STEP == sizeof(v128_t), "invalid vector size mul");
|
|
||||||
|
|
||||||
#define INPUT_VPROC_STEP 15
|
|
||||||
|
|
||||||
__attribute__((pure))
|
|
||||||
u64 vproc(usize len, const input_t input[const restrict len])
|
|
||||||
{
|
|
||||||
static const v128_t SINGLE = { .as.i16 = { -1, -1, -1, -1, -1, -1, -1, -1 } };
|
|
||||||
static const v128_t ONES = { .as.i16 = { 1, 1, 1, 1, 1, 1, 1, 1 } };
|
|
||||||
#if DEBUG
|
|
||||||
assert(len % INPUT_VPROC_STEP == 0);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define LAST(j) input[i + (j)]
|
|
||||||
#define NEXT(j) input[i + ((j) * 2)]
|
|
||||||
__m128i end = _mm_setzero_si128();
|
|
||||||
for(usize i = 0;i<len;i+=INPUT_VPROC_STEP)
|
|
||||||
{
|
|
||||||
// load the vectors
|
|
||||||
v128_t prev = { .as.u16 = {
|
|
||||||
input[i+0],
|
|
||||||
input[i+2],
|
|
||||||
|
|
||||||
input[i+4],
|
|
||||||
input[i+6],
|
|
||||||
|
|
||||||
input[i+8],
|
|
||||||
input[i+10],
|
|
||||||
|
|
||||||
input[i+12],
|
|
||||||
input[i+14],
|
|
||||||
}
|
|
||||||
};
|
|
||||||
v128_t next = { .as.u16 = {
|
|
||||||
input[i+1],
|
|
||||||
input[i+3],
|
|
||||||
|
|
||||||
input[i+5],
|
|
||||||
input[i+7],
|
|
||||||
|
|
||||||
input[i+9],
|
|
||||||
input[i+11],
|
|
||||||
|
|
||||||
input[i+13],
|
|
||||||
input[i+15],
|
|
||||||
}
|
|
||||||
};
|
|
||||||
//__m128i res = _mm_subs_epi16(prev.mm, next.mm);
|
|
||||||
__m128i pltn = _mm_cmplt_epi16(prev.mm, next.mm); // prev < next
|
|
||||||
pltn = _mm_sign_epi16(pltn, SINGLE.mm);
|
|
||||||
pltn = _mm_sign_epi16(ONES.mm, pltn);
|
|
||||||
end = _mm_add_epi16(end, pltn);
|
|
||||||
//__m128i pr = _mm_sign_epi16(FULL_MASK.mm, res);
|
|
||||||
}
|
|
||||||
|
|
||||||
v16_u128n _ev = ((union v128)end).as.u16;
|
|
||||||
return (u64) ( _ev[0] + _ev[1]
|
|
||||||
+ _ev[2] + _ev[3]
|
|
||||||
+ _ev[4] + _ev[5]
|
|
||||||
+ _ev[6] + _ev[7] );
|
|
||||||
}
|
|
Loading…
Reference in new issue