noobie
1
I’m trying to understand the reasoning behind the <
checks in this SIMD code.
The relevant part is:
if (i + 2 * block_len < slice.len) {
const mask: Block = @splat(value);
while (true) {
inline for (0..2) |_| {
const block: Block = slice[i..][0..block_len].*;
const matches = block == mask;
if (@reduce(.Or, matches)) {
return i + std.simd.firstTrue(matches).?;
}
i += block_len;
}
if (i + 2 * block_len >= slice.len) break;
}
}
Then the tail handling has:
const block_x_len = block_len / (1 << j);
if (i + block_x_len < slice.len) {
const block: BlockX = slice[i..][0..block_x_len].*;
...
}
I’m wondering why these use <
instead of <=
.
If a block ends exactly at slice.len
, wouldn’t it still be valid? For example, if slice.len == 16
and block_len == 8
, the block [8..16)
fits completely.
With <
, that final block is left for the scalar loop instead.
I’m mainly trying to understand if there is a performance, bounds-check, or other implementation reason for using <
here that I’m missing.
Looks to me like the usual difference between Offset (i
) and Size (slice.len
). There is a nice visualization at TigerBeetles Blog post Index, Count, Offset, Size
I think the use of <
is appropriate here.
noobie
3
I see the index/count distinction, but in this case I think i + block_len
is an end position rather than an index. If i = 8
, block_len = 8
, and slice.len = 16
, the accessed range is [8..16)
, so the block fits exactly. That’s why I’m wondering why the condition uses <
rather than <=
.