From cefec3ce9dc6430ac546b2e4985f917adfa0d513 Mon Sep 17 00:00:00 2001 From: Mahesh Madhav Date: Sat, 5 Oct 2024 05:40:19 +0000 Subject: [PATCH 1/5] Reduce fdiv's into fmul's Provides small speedup on microarchitectures where the floating point divide is slower than the floating point multiply. --- c/enc/block_splitter_inc.h | 2 +- c/enc/encode.c | 5 +++-- c/enc/literal_cost.c | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/c/enc/block_splitter_inc.h b/c/enc/block_splitter_inc.h index aa40bfd..6668d5e 100644 --- a/c/enc/block_splitter_inc.h +++ b/c/enc/block_splitter_inc.h @@ -129,7 +129,7 @@ static size_t FN(FindBlocks)(const DataType* data, const size_t length, } /* More blocks for the beginning. */ if (byte_ix < 2000) { - block_switch_cost *= 0.77 + 0.07 * (double)byte_ix / 2000; + block_switch_cost *= 0.77 + 0.00003 * (double)byte_ix; } for (k = 0; k < num_histograms; ++k) { cost[k] -= min_cost; diff --git a/c/enc/encode.c b/c/enc/encode.c index 8ea6eee..a2cc7cb 100644 --- a/c/enc/encode.c +++ b/c/enc/encode.c @@ -437,10 +437,11 @@ static BROTLI_BOOL ShouldCompress( if ((double)num_literals > 0.99 * (double)bytes) { uint32_t literal_histo[256] = { 0 }; static const uint32_t kSampleRate = 13; + static const double invKSampleRate = 1.0 / 13.0; static const double kMinEntropy = 7.92; const double bit_cost_threshold = - (double)bytes * kMinEntropy / kSampleRate; - size_t t = (bytes + kSampleRate - 1) / kSampleRate; + (double)bytes * kMinEntropy * invKSampleRate; + size_t t = (bytes + kSampleRate - 1) * invKSampleRate; uint32_t pos = (uint32_t)last_flush_pos; size_t i; for (i = 0; i < t; i++) { diff --git a/c/enc/literal_cost.c b/c/enc/literal_cost.c index 2ac847f..fafc7f6 100644 --- a/c/enc/literal_cost.c +++ b/c/enc/literal_cost.c @@ -121,7 +121,7 @@ static void EstimateBitCostsForLiteralsUTF8(size_t pos, size_t len, size_t mask, rapidly in the beginning of the file, perhaps because the beginning of the data is a statistical "anomaly". */ if (i < 2000) { - lit_cost += 0.7 - ((double)(2000 - i) / 2000.0 * 0.35); + lit_cost += 0.7 - ((double)(2000 - i) * 0.000175); } cost[i] = (float)lit_cost; } From cec846f88e7e632933773b2c3c43d3ad13992e96 Mon Sep 17 00:00:00 2001 From: Mahesh Madhav <67384846+heshpdx@users.noreply.github.com> Date: Sat, 5 Oct 2024 10:46:27 -0700 Subject: [PATCH 2/5] Update c/enc/block_splitter_inc.h Added a digit of precision --- c/enc/block_splitter_inc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/c/enc/block_splitter_inc.h b/c/enc/block_splitter_inc.h index 6668d5e..bf62358 100644 --- a/c/enc/block_splitter_inc.h +++ b/c/enc/block_splitter_inc.h @@ -129,7 +129,7 @@ static size_t FN(FindBlocks)(const DataType* data, const size_t length, } /* More blocks for the beginning. */ if (byte_ix < 2000) { - block_switch_cost *= 0.77 + 0.00003 * (double)byte_ix; + block_switch_cost *= 0.77 + 0.000035 * (double)byte_ix; } for (k = 0; k < num_histograms; ++k) { cost[k] -= min_cost; From 1054ecc262a046e3368ca77c70c945c61a6d9a8b Mon Sep 17 00:00:00 2001 From: Mahesh Madhav Date: Tue, 12 Nov 2024 16:25:30 +0000 Subject: [PATCH 3/5] Add static variables as per code review comments. --- c/enc/block_splitter_inc.h | 3 ++- c/enc/literal_cost.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/c/enc/block_splitter_inc.h b/c/enc/block_splitter_inc.h index bf62358..7e96204 100644 --- a/c/enc/block_splitter_inc.h +++ b/c/enc/block_splitter_inc.h @@ -118,6 +118,7 @@ static size_t FN(FindBlocks)(const DataType* data, const size_t length, size_t insert_cost_ix = symbol * num_histograms; double min_cost = 1e99; double block_switch_cost = block_switch_bitcost; + static const double threshold = 0.07 / 2000.0; size_t k; for (k = 0; k < num_histograms; ++k) { /* We are coding the symbol with entropy code k. */ @@ -129,7 +130,7 @@ static size_t FN(FindBlocks)(const DataType* data, const size_t length, } /* More blocks for the beginning. */ if (byte_ix < 2000) { - block_switch_cost *= 0.77 + 0.000035 * (double)byte_ix; + block_switch_cost *= 0.77 + threshold * (double)byte_ix; } for (k = 0; k < num_histograms; ++k) { cost[k] -= min_cost; diff --git a/c/enc/literal_cost.c b/c/enc/literal_cost.c index fafc7f6..b063afc 100644 --- a/c/enc/literal_cost.c +++ b/c/enc/literal_cost.c @@ -106,6 +106,7 @@ static void EstimateBitCostsForLiteralsUTF8(size_t pos, size_t len, size_t mask, size_t utf8_pos = UTF8Position(last_c, c, max_utf8); size_t masked_pos = (pos + i) & mask; size_t histo = histogram[256 * utf8_pos + data[masked_pos]]; + static const double threshold = 0.35 / 2000.0; double lit_cost; if (histo == 0) { histo = 1; @@ -121,7 +122,7 @@ static void EstimateBitCostsForLiteralsUTF8(size_t pos, size_t len, size_t mask, rapidly in the beginning of the file, perhaps because the beginning of the data is a statistical "anomaly". */ if (i < 2000) { - lit_cost += 0.7 - ((double)(2000 - i) * 0.000175); + lit_cost += 0.7 - ((double)(2000 - i) * threshold); } cost[i] = (float)lit_cost; } From 782aadd0ff957d738412508bd07cafa55b399a49 Mon Sep 17 00:00:00 2001 From: Mahesh Madhav <67384846+heshpdx@users.noreply.github.com> Date: Tue, 12 Nov 2024 14:45:06 -0800 Subject: [PATCH 4/5] Apply suggestions from code review Co-authored-by: Eugene Kliuchnikov --- c/enc/block_splitter_inc.h | 7 ++++--- c/enc/literal_cost.c | 7 ++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/c/enc/block_splitter_inc.h b/c/enc/block_splitter_inc.h index 7e96204..64409ec 100644 --- a/c/enc/block_splitter_inc.h +++ b/c/enc/block_splitter_inc.h @@ -118,7 +118,8 @@ static size_t FN(FindBlocks)(const DataType* data, const size_t length, size_t insert_cost_ix = symbol * num_histograms; double min_cost = 1e99; double block_switch_cost = block_switch_bitcost; - static const double threshold = 0.07 / 2000.0; + static const size_t prologue_length = 2000; + static const double multiplier = 0.07 / 2000; size_t k; for (k = 0; k < num_histograms; ++k) { /* We are coding the symbol with entropy code k. */ @@ -129,8 +130,8 @@ static size_t FN(FindBlocks)(const DataType* data, const size_t length, } } /* More blocks for the beginning. */ - if (byte_ix < 2000) { - block_switch_cost *= 0.77 + threshold * (double)byte_ix; + if (byte_ix < prologue_length) { + block_switch_cost *= 0.77 + multiplier * (double)byte_ix; } for (k = 0; k < num_histograms; ++k) { cost[k] -= min_cost; diff --git a/c/enc/literal_cost.c b/c/enc/literal_cost.c index b063afc..a129657 100644 --- a/c/enc/literal_cost.c +++ b/c/enc/literal_cost.c @@ -106,7 +106,8 @@ static void EstimateBitCostsForLiteralsUTF8(size_t pos, size_t len, size_t mask, size_t utf8_pos = UTF8Position(last_c, c, max_utf8); size_t masked_pos = (pos + i) & mask; size_t histo = histogram[256 * utf8_pos + data[masked_pos]]; - static const double threshold = 0.35 / 2000.0; + static const size_t prologue_length = 2000; + static const double multiplier = 0.35 / 2000; double lit_cost; if (histo == 0) { histo = 1; @@ -121,8 +122,8 @@ static void EstimateBitCostsForLiteralsUTF8(size_t pos, size_t len, size_t mask, Perhaps because the entropy source is changing its properties rapidly in the beginning of the file, perhaps because the beginning of the data is a statistical "anomaly". */ - if (i < 2000) { - lit_cost += 0.7 - ((double)(2000 - i) * threshold); + if (i < prologue_length) { + lit_cost += 0.35 + multiplier * (double)i; } cost[i] = (float)lit_cost; } From 8c6d25f7f8fab5b0793b7632481a8c609a8184e9 Mon Sep 17 00:00:00 2001 From: Mahesh Madhav <67384846+heshpdx@users.noreply.github.com> Date: Fri, 15 Nov 2024 10:39:15 -0800 Subject: [PATCH 5/5] Update c/enc/encode.c Co-authored-by: Eugene Kliuchnikov --- c/enc/encode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/c/enc/encode.c b/c/enc/encode.c index a2cc7cb..a8fdcad 100644 --- a/c/enc/encode.c +++ b/c/enc/encode.c @@ -441,7 +441,7 @@ static BROTLI_BOOL ShouldCompress( static const double kMinEntropy = 7.92; const double bit_cost_threshold = (double)bytes * kMinEntropy * invKSampleRate; - size_t t = (bytes + kSampleRate - 1) * invKSampleRate; + size_t t = (double)(bytes + kSampleRate - 1) * invKSampleRate; uint32_t pos = (uint32_t)last_flush_pos; size_t i; for (i = 0; i < t; i++) {