image_preprocessing: write whole elements out of the un-transpose
The raw-bytes path assembled each element a byte at a time, which on a full frame cost about 4x against writing the 8 contiguous elements a thread owns through an element-typed pointer. They are 8*ES-byte aligned, so the compiler merges them. 72.4 MB frame: 1.524 -> 0.406 ms for upload plus both kernels. The test now also times the LZ4 pass on its own, so the bounds and validity checks in the hot loop can be costed rather than guessed at. They are free: 0.231 ms against 0.2297 ms measured for the kernel before any of them existed - the restored offset == 1 and power-of-two fast paths pay for them. compute-sanitizer memcheck reports no error over 400 single-bit-corrupted payloads and nine malformed containers. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -678,6 +678,15 @@ TEST_CASE("BSLZ4Fuzz_LargeFrame", "[BSLZ4Fuzz]") {
|
||||
REQUIRE(cudaStreamSynchronize(*stream) == cudaSuccess);
|
||||
auto t3 = std::chrono::steady_clock::now();
|
||||
|
||||
// The LZ4 pass on its own (upload + parse), so the bounds and validity checks in the hot loop
|
||||
// can be costed against the un-transpose rather than hidden behind it.
|
||||
auto t4 = std::chrono::steady_clock::now();
|
||||
for (int i = 0; i < reps; i++) decoder.DecodeShuffled(image);
|
||||
REQUIRE(cudaStreamSynchronize(*stream) == cudaSuccess);
|
||||
auto t5 = std::chrono::steady_clock::now();
|
||||
printf("[BSLZ4Fuzz] LZ4 pass alone (upload + parse) %.3f ms\n",
|
||||
std::chrono::duration<double, std::milli>(t5 - t4).count() / reps);
|
||||
|
||||
const double cpu_ms = std::chrono::duration<double, std::milli>(t1 - t0).count();
|
||||
const double gpu_ms = std::chrono::duration<double, std::milli>(t3 - t2).count() / reps;
|
||||
printf("[BSLZ4Fuzz] large frame %zux%zu uint32 = %.1f MB, compressed %.1f MB (%.2fx), %zu blocks\n",
|
||||
|
||||
Reference in New Issue
Block a user