Approximate FastLog between value range [256, 8192]

Profiled data: Profiled few images and found that in the function VP8LFastLog,
90% of time table lookup is performed, while rest of time (10%) call to log
function is made. Typical lookup accounts for 10 CPU instructions and call to
log 200 instruction counts. The weighted average comes out to be 30
instructions per call. For mid qualities (25-75), this function (VP8LFastLog)
accounts for 30-50% of total CPU cycles (via call path: VP8LCOlorSpaceTransform
-> PredictionCostCrossColor -> ShannonEntropy). After this change, the log is
called less that 1% of time, with average instructions being 15 per call.
Measured the performance over 1000 files for various qualities and found
overall compression speedup between 10-15% (in quality range [0, 75]). The
compression density loss is around 0.5% (though at some qualities, compression
is little better as well).

Change-Id: I247bc6a8d4351819c871f19d65455dc23aea8650
This commit is contained in:
Vikas Arora 2012-04-27 11:06:24 +00:00 committed by James Zern
parent ec123ca3f6
commit ada6ff77df
2 changed files with 14 additions and 5 deletions

View File

@ -28,7 +28,8 @@ extern "C" {
// computation.
//
// ", ".join(["%.16ff" % x for x in [0.0]+[log(x) for x in range(1, 256)]])
static const float kLogTable[] = {
#define LOG_LOOKUP_IDX_MAX 256
static const float kLogTable[LOG_LOOKUP_IDX_MAX] = {
0.0000000000000000f, 0.0000000000000000f, 0.6931471805599453f,
1.0986122886681098f, 1.3862943611198906f, 1.6094379124341003f,
1.7917594692280550f, 1.9459101490553132f, 2.0794415416798357f,
@ -117,9 +118,17 @@ static const float kLogTable[] = {
5.5412635451584258f
};
double VP8LFastLog(int v) {
if (v < (int)(sizeof(kLogTable) / sizeof(kLogTable[0]))) {
return kLogTable[v];
#define APPROX_LOG_MAX 4096
#define LOG_2_BASE_E 0.6931471805599453f
float VP8LFastLog(int v) {
if (v < APPROX_LOG_MAX) {
int log_cnt = 0;
while (v >= LOG_LOOKUP_IDX_MAX) {
++log_cnt;
v = v >> 1;
}
return kLogTable[v] + (log_cnt * LOG_2_BASE_E);
}
return log(v);
}

View File

@ -64,7 +64,7 @@ static WEBP_INLINE uint32_t VP8LSubSampleSize(uint32_t size,
#ifdef USE_LOSSLESS_ENCODER
// Faster logarithm for small integers, with the property of log(0) == 0.
double VP8LFastLog(int v);
float VP8LFastLog(int v);
// In-place difference of each component with mod 256.
static WEBP_INLINE uint32_t VP8LSubPixels(uint32_t a, uint32_t b) {