Adding benchmark.

This commit is contained in:
Daniel Lemire
2018-07-18 22:34:41 -04:00
parent 95ed58be44
commit cae582232f
4 changed files with 17 additions and 41 deletions
+6 -6
View File
@@ -85,7 +85,7 @@ int main(int argc, char *argv[]) {
int repeat = 10;
int volume = p.second;
BEST_TIME_NOCHECK(avx_json_parse(p.first, p.second, pj), , repeat, volume,
BEST_TIME(avx_json_parse(p.first, p.second, pj), true , , repeat, volume,
true);
rapidjson::Document d;
@@ -108,18 +108,18 @@ int main(int argc, char *argv[]) {
true);
memcpy(buffer, p.first, p.second);
size_t outlength = copy_without_useless_spaces((const uint8_t *)buffer, p.second,(uint8_t *) buffer);
size_t outlength = copy_without_useless_spaces_avx((const uint8_t *)buffer, p.second,(uint8_t *) buffer);
printf("these should match: %zu %zu \n", strlength, outlength);
uint8_t * cbuffer = (uint8_t *)buffer;
BEST_TIME(copy_without_useless_spaces(cbuffer, p.second,cbuffer), outlength,
BEST_TIME(copy_without_useless_spaces_avx(cbuffer, p.second,cbuffer), outlength,
memcpy(buffer, p.first, p.second), repeat, volume, true);
BEST_TIME(despace(cbuffer, p.second,cbuffer), outlength,
BEST_TIME(scalar_despace(cbuffer, p.second,cbuffer), outlength,
memcpy(buffer, p.first, p.second), repeat, volume, true);
BEST_TIME(d.ParseInsitu(buffer).HasParseError(),false, cbuffer[copy_without_useless_spaces((const uint8_t *)p.first, p.second,cbuffer)]='\0' , repeat, volume,
printf("parsing with RapidJSON after despacing:\n");
BEST_TIME(d.ParseInsitu(buffer).HasParseError(),false, cbuffer[copy_without_useless_spaces_avx((const uint8_t *)p.first, p.second,cbuffer)]='\0' , repeat, volume,
true);
free(buffer);
+1 -30
View File
@@ -33,7 +33,7 @@ static uint64_t cmp_mask_against_input_mini(__m256i input_lo, __m256i input_hi,
// take input from buf and remove useless whitespace, input and output can be
// the same
static inline size_t copy_without_useless_spaces(const uint8_t *buf, size_t len,
static inline size_t copy_without_useless_spaces_avx(const uint8_t *buf, size_t len,
uint8_t *out) {
// Useful constant masks
const uint64_t even_bits = 0x5555555555555555ULL;
@@ -163,36 +163,7 @@ static inline size_t copy_without_useless_spaces(const uint8_t *buf, size_t len,
_mm_set_epi64x(0ULL, quote_bits), _mm_set1_epi8(0xFF), 0));
quote_mask ^= prev_iter_inside_quote;
prev_iter_inside_quote = (uint64_t)((s64)quote_mask >> 63);
/*
const __m256i low_nibble_mask = _mm256_setr_epi8(
// 0 9 a b c d
16, 0, 0, 0, 0, 0, 0, 0, 0, 8, 12, 1, 2, 9, 0, 0, 16, 0, 0, 0, 0, 0, 0,
0, 0, 8, 12, 1, 2, 9, 0, 0);
const __m256i high_nibble_mask = _mm256_setr_epi8(
// 0 2 3 5 7
8, 0, 18, 4, 0, 1, 0, 1, 0, 0, 0, 3, 2, 1, 0, 0, 8, 0, 18, 4, 0, 1, 0,
1, 0, 0, 0, 3, 2, 1, 0, 0);
__m256i whitespace_shufti_mask = _mm256_set1_epi8(0x18);
__m256i v_lo = _mm256_and_si256(
_mm256_shuffle_epi8(low_nibble_mask, input_lo),
_mm256_shuffle_epi8(high_nibble_mask,
_mm256_and_si256(_mm256_srli_epi32(input_lo, 4),
_mm256_set1_epi8(0x7f))));
__m256i v_hi = _mm256_and_si256(
_mm256_shuffle_epi8(low_nibble_mask, input_hi),
_mm256_shuffle_epi8(high_nibble_mask,
_mm256_and_si256(_mm256_srli_epi32(input_hi, 4),
_mm256_set1_epi8(0x7f))));
__m256i tmp_ws_lo = _mm256_cmpeq_epi8(
_mm256_and_si256(v_lo, whitespace_shufti_mask), _mm256_set1_epi8(0));
__m256i tmp_ws_hi = _mm256_cmpeq_epi8(
_mm256_and_si256(v_hi, whitespace_shufti_mask), _mm256_set1_epi8(0));
uint64_t ws_res_0 = (uint32_t)_mm256_movemask_epi8(tmp_ws_lo);
uint64_t ws_res_1 = _mm256_movemask_epi8(tmp_ws_hi);
uint64_t whitespace = ~(ws_res_0 | (ws_res_1 << 32));
*/
__m256i mask_20 = _mm256_set1_epi8(0x20); // c==32
__m256i mask_70 =
_mm256_set1_epi8(0x70); // adding 0x70 does not check low 4-bits
+9 -4
View File
@@ -432,7 +432,6 @@ never_inline void init_state_machine() {
}
never_inline bool ape_machine(const u8 * buf, UNUSED size_t len, ParsedJson & pj) {
// NOTE - our depth is used by both the tape machine and the state machine
// Further, in production we will set it to a largish value in a generous buffer as a rogue input
// could consist of many {[ characters or many }] characters. We aren't busily checking errors
@@ -512,12 +511,13 @@ never_inline bool ape_machine(const u8 * buf, UNUSED size_t len, ParsedJson & pj
tape[tape_locs[depth]] = write_val | (((u64)c) << 56);
old_tape_loc = tape_locs[depth] += write_size;
}
/*
for (u32 i = 0; i < MAX_DEPTH; i++) {
if (states[i] == 0) {
printf("duuh\n");
return false;
}
}
}*/
#define DUMP_TAPES
#ifdef DEBUG
@@ -547,6 +547,7 @@ never_inline bool ape_machine(const u8 * buf, UNUSED size_t len, ParsedJson & pj
}
#endif
if (error_sump) {
printf("error_sump\n");
return false;
}
return true;
@@ -1090,5 +1091,9 @@ never_inline bool shovel_machine(const u8 * buf, size_t len, ParsedJson & pj) {
static bool avx_json_parse(const u8 * buf, size_t len, ParsedJson & pj) {
find_structural_bits(buf, len, pj);
flatten_indexes(len, pj);
return ape_machine(buf, len, pj) && shovel_machine(buf, len, pj);
bool apeok = ape_machine(buf, len, pj);
if(!apeok) {
return false;
}
return shovel_machine(buf, len, pj);
}
+1 -1
View File
@@ -34,7 +34,7 @@ static uint8_t jump_table[256 * 3] = {
0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1,
};
static inline size_t despace(const unsigned char *bytes, size_t howmany,
static inline size_t scalar_despace(const unsigned char *bytes, size_t howmany,
unsigned char *out) {
size_t i = 0, pos = 0;
uint8_t quote = 0;