Skip to content

Commit

Permalink
only load 128 bit block once
Browse files Browse the repository at this point in the history
  • Loading branch information
JairusSW committed Nov 7, 2024
1 parent ebc3a0d commit 28c0197
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 66 deletions.
11 changes: 6 additions & 5 deletions assembly/__benches__/misc.bench.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,17 @@ import { serializeString } from "../serialize/simple/string";
import { serializeString_BS } from "../serialize/bs/string";
import { bs } from "../custom/bs";

// bench("Serialize String (Simple)", () => {
// blackbox<string>(serializeString("h\\ello w"));
// });
const str = "hello wo"
bench("Serialize String (Simple)", () => {
serializeString(str);
});

// bench("Serialize String (BS)", () => {
// serializeString_BS("h\\ello w");
// bs.reset();
// });

const out = new ArrayBuffer(22);
const out = new ArrayBuffer(16);
bench("Serialize String (SIMD)", () => {
blackbox<usize>(serializeString_SIMD("hello wo", changetype<usize>(out)));
serializeString_SIMD(str, changetype<usize>(out));
});
100 changes: 39 additions & 61 deletions assembly/serialize/simd/string.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,78 +12,56 @@ const SPLAT_32 = i16x8.splat(32); /* [ESC] */
*/
// @ts-ignore: Decorator
@inline export function serializeString_SIMD(src: string, dst: usize): usize {
if (isDefined(ASC_FEATURE_SIMD)) {
let src_ptr = changetype<usize>(src);
let dst_ptr = changetype<usize>(dst) + 2;
let src_ptr = changetype<usize>(src);
let dst_ptr = changetype<usize>(dst) + 2;

store<u8>(changetype<usize>(dst), 34); /* " */
const src_end = src_ptr + changetype<OBJECT>(changetype<usize>(src) - TOTAL_OVERHEAD).rtSize;
const src_end_15 = src_end - 15;
const src_end = src_ptr + changetype<OBJECT>(changetype<usize>(src) - TOTAL_OVERHEAD).rtSize;
const src_end_15 = src_end - 15;

while (src_ptr < src_end_15) {
const block = v128.load(src_ptr);
store<u8>(changetype<usize>(dst), 34); /* " */

const backslash_indices = i16x8.eq(block, SPLAT_92);
const quote_indices = i16x8.eq(block, SPLAT_34);
const char_indices = v128.or(quote_indices, backslash_indices);
while (src_ptr < src_end_15) {
const block = v128.load(src_ptr);

const escape_indices = i16x8.lt_u(block, SPLAT_32);
const backslash_indices = i16x8.eq(block, SPLAT_92);
const quote_indices = i16x8.eq(block, SPLAT_34);
const char_indices = v128.or(quote_indices, backslash_indices);

if (v128.any_true(char_indices)) {
let mask = i16x8.bitmask(char_indices);
let lane_index = ctz(mask) << 1;
const escape_indices = i16x8.lt_u(block, SPLAT_32);
const sieve = v128.or(char_indices, escape_indices);

v128.store(dst_ptr, v128.load(src_ptr));
if (v128.any_true(sieve)) {
let char_mask = i16x8.bitmask(char_indices);

while (mask != 0) {
const dst_offset = dst_ptr + lane_index;
store<u16>(dst_offset, 92); /* \ */
v128.store(dst_offset, v128.load(src_ptr + lane_index), 2);
mask &= mask - 1;
lane_index = ctz(mask) << 1;
dst_ptr += 2;
}
v128.store(dst_ptr, block);

dst_ptr += 16;
src_ptr += 16;
} else if (v128.any_true(escape_indices)) {
let mask = i16x8.bitmask(escape_indices);
let lane_index = ctz(mask) << 1;

v128.store(dst_ptr, v128.load(src_ptr));

while (mask != 0) {
const dst_offset = dst_ptr + lane_index;
store<u16>(dst_offset, 92); /* \ */
v128.store(dst_offset, v128.load(src_ptr + lane_index), 2);
mask &= mask - 1;
lane_index = ctz(mask) << 1;
dst_ptr += 2;
}

dst_ptr += 16;
src_ptr += 16;
} else {
v128.store(dst_ptr, block);
src_ptr += 16;
dst_ptr += 16;
}
do {
const lane_index = ctz(char_mask) << 1;
const dst_offset = dst_ptr + lane_index;
store<u16>(dst_offset, 92); /* \ */
v128.store(dst_offset, v128.load(src_ptr + lane_index), 2);
char_mask &= char_mask - 1;
dst_ptr += 2;
} while (char_mask != 0)
} else {
v128.store(dst_ptr, block);
}

while (src_ptr < src_end) {
let char_code = load<u16>(src_ptr);
if (char_code == 92 || char_code == 34) {
store<u16>(dst_ptr, 92);
dst_ptr += 2;
}
store<u16>(dst_ptr, char_code);
src_ptr += 16;
dst_ptr += 16;
}

do {
let char_code = load<u16>(src_ptr);
if (char_code == 92 || char_code == 34) {
store<u16>(dst_ptr, 92);
dst_ptr += 2;
src_ptr += 2;
}
store<u16>(dst_ptr, char_code);
dst_ptr += 2;
src_ptr += 2;
} while (src_ptr < src_end);

store<u8>(dst_ptr, 34);
return dst_ptr - changetype<usize>(dst) + 2;
} else {
return 0;
}
store<u8>(dst_ptr, 34); /* " */
return 0//dst_ptr - changetype<usize>(dst) + 2;
}

0 comments on commit 28c0197

Please sign in to comment.