CBF byte-offset decoder: plain stores instead of SSE streaming stores
The host decoder wrote each pixel with _mm_stream_si32 and ended with _mm_sfence, to keep the decoded frame out of the cache on its way to the GPU by DMA. The GPU now decodes CBF itself, so the host decoder only serves the CPU engines and the tests, and the project rule is no SIMD intrinsics. Plain stores; the values written are the same. CBFDecoderGPU_MatchesHost, CBFDecoderGPU_ShortStreamIsRefused, ImagePreprocessorGPU_StoredEncodingsMatchCPU and the CBF reader tests pass. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EizBKhTqrAYago9KJG3dA3
This commit is contained in:
@@ -6,11 +6,6 @@
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
|
||||
#if defined(__SSE2__) || defined(_M_X64) || defined(_M_AMD64)
|
||||
# include <emmintrin.h>
|
||||
# define MINICBF_STREAM_STORE 1
|
||||
#endif
|
||||
|
||||
#include "../common/JFJochException.h"
|
||||
|
||||
namespace {
|
||||
@@ -19,26 +14,6 @@ int16_t ReadI16(const uint8_t *p) { int16_t v; std::memcpy(&v, p, 2); return v;
|
||||
int32_t ReadI32(const uint8_t *p) { int32_t v; std::memcpy(&v, p, 4); return v; }
|
||||
int64_t ReadI64(const uint8_t *p) { int64_t v; std::memcpy(&v, p, 8); return v; }
|
||||
|
||||
// Nothing on this side reads the decoded image back: it goes to the GPU by DMA, or a CPU engine
|
||||
// walks it once and drops it. An ordinary store therefore pays twice over - it reads every cache
|
||||
// line before overwriting it, and it evicts 72 MB of live cache to make room - so the pixels go
|
||||
// straight past the cache. Measured on an 18 Mpx frame: 27 ms of ordinary stores against 11 ms of
|
||||
// these. The bytes written are the same either way; the fence is what makes them visible to the
|
||||
// copy that follows.
|
||||
void StorePixel(int32_t *out, int32_t value) {
|
||||
#ifdef MINICBF_STREAM_STORE
|
||||
_mm_stream_si32(out, value);
|
||||
#else
|
||||
*out = value;
|
||||
#endif
|
||||
}
|
||||
|
||||
void StoreFence() {
|
||||
#ifdef MINICBF_STREAM_STORE
|
||||
_mm_sfence();
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// The x-CBF_BYTE_OFFSET scheme: a running value, each pixel stored as a delta in the smallest
|
||||
@@ -75,12 +50,10 @@ void DecodeCBFByteOffset(const uint8_t *data, size_t size, int32_t *out, size_t
|
||||
}
|
||||
|
||||
value += delta;
|
||||
StorePixel(out + written, static_cast<int32_t>(value));
|
||||
out[written] = static_cast<int32_t>(value);
|
||||
written++;
|
||||
}
|
||||
|
||||
StoreFence();
|
||||
|
||||
if (written != n_pixels)
|
||||
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
|
||||
"miniCBF byte-offset stream ended after " + std::to_string(written)
|
||||
|
||||
Reference in New Issue
Block a user