day1: part 1 complete

Fortune for aoc2021's current commit: Curse − 凶
master
Avril 2 years ago
parent a8dce41cc4
commit 7598a8d6b9
Signed by: flanchan
GPG Key ID: 284488987C31F630

@ -0,0 +1,3 @@
#TODO: How to lay this out?
day%/: day%/day%-release

@ -9,9 +9,13 @@ SRC_CXX = $(wildcard src/*.cpp)
INCLUDE=include
INPUT_SOURCE=input
INPUT_DEST=src/input.c
COMMON_FLAGS+= -W -Wall -fno-strict-aliasing $(addprefix -I,$(INCLUDE))
COMMON_FLAGS+=-msse -msse2 -msse3
COMMON_FLAGS+=-D_PART1
OPT_FLAGS?= -march=native -fgraphite -fopenmp -floop-parallelize-all -ftree-parallelize-loops=4 \
-floop-interchange -ftree-loop-distribution -floop-strip-mine -floop-block \
@ -53,16 +57,21 @@ OBJ = $(OBJ_C) $(OBJ_CXX)
# Phonies
.PHONY: release
release: | dirs $(PROJECT)-release
release: | dirs $(INPUT_DEST)
$(MAKE) $(PROJECT)-release
.PHONY: debug
debug: | dirs $(PROJECT)-debug
debug: | dirs $(INPUT_DEST)
$(MAKE) $(PROJECT)-debug
# Targets
dirs:
@mkdir -p obj/c{,xx}/src
$(INPUT_DEST): $(INPUT_SOURCE)
./mkinput $< > $@
obj/c/%.o: %.c
$(CC) -c $< $(CFLAGS) -o $@ $(LDFLAGS)
@ -87,4 +96,5 @@ clean-rebuild:
clean: clean-rebuild
rm -f $(PROJECT)-{release,debug,pgo}
rm -f $(INPUT_DEST)

@ -10,11 +10,14 @@ extern "C" {
typedef uint16_t input_t;
#define INPUT_VECTOR_STEP (16 / sizeof(input_t))
extern const size_t INPUT_SIZE;
extern const input_t INPUT[];
struct ipair {
input_t prev;
input_t next;
};
#ifdef __cplusplus
}
#endif

@ -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 */

@ -1,6 +1,6 @@
#!/bin/bash
INPUT=${INPUT:-input}
INPUT=${1:-input}
NUM=$(wc -l < ${INPUT})

@ -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…
Cancel
Save