This helps compiler figure out it can unroll loop and give 4x speedup.
Showing the changes to libavfilter (1 of 1 file). Show all
Unified · Split
| @@ -148,25 +148,29 @@ static int config_output(AVFilterLink *outlink) · 147 unmodified lines | |||
| 148 | return 0; | 148 | return 0; |
| 149 | } | 149 | } |
| 150 | 150 | ||
| 151 | #define BITCOUNTER(type, depth, one) \ | ||
| 152 | memset(counter, 0, sizeof(s->counter)); \ | ||
| 153 | for (int i = 0; i < nb_samples; i++) { \ | ||
| 154 | const type x = in[i]; \ | ||
| 155 | for (int j = 0; j < depth && x; j++) \ | ||
| 156 | counter[j] += !!(x & (one << j)); \ | ||
| 157 | } | ||
| 158 | |||
| 151 | #define BARS(type, depth, one) \ | 159 | #define BARS(type, depth, one) \ |
| 152 | for (int ch = 0; ch < inlink->ch_layout.nb_channels; ch++) { \ | 160 | for (int ch = 0; ch < inlink->ch_layout.nb_channels; ch++) { \ |
| 161 | const int nb_samples = insamples->nb_samples; \ | ||
| 153 | const type *in = (const type *)insamples->extended_data[ch]; \ | 162 | const type *in = (const type *)insamples->extended_data[ch]; \ |
| 154 | const int w = outpicref->width / inlink->ch_layout.nb_channels; \ | 163 | const int w = outpicref->width / inlink->ch_layout.nb_channels; \ |
| 155 | const int h = outpicref->height / depth; \ | 164 | const int h = outpicref->height / depth; \ |
| 156 | const uint32_t color = AV_RN32(&s->fg[4 * ch]); \ | 165 | const uint32_t color = AV_RN32(&s->fg[4 * ch]); \ |
| 166 | uint64_t *counter = s->counter; \ | ||
| 157 | \ | 167 | \ |
| 158 | memset(s->counter, 0, sizeof(s->counter)); \ | 168 | BITCOUNTER(type, depth, one) \ |
| 159 | for (int i = 0; i < insamples->nb_samples; i++) { \ | ||
| 160 | for (int j = 0; j < depth; j++) { \ | ||
| 161 | if (in[i] & (one << j)) \ | ||
| 162 | s->counter[j]++; \ | ||
| 163 | } \ | ||
| 164 | } \ | ||
| 165 | \ | 169 | \ |
| 166 | for (int b = 0; b < depth; b++) { \ | 170 | for (int b = 0; b < depth; b++) { \ |
| 167 | for (int j = 1; j < h - 1; j++) { \ | 171 | for (int j = 1; j < h - 1; j++) { \ |
| 168 | uint8_t *dst = outpicref->data[0] + (b * h + j) * outpicref->linesize[0] + w * ch * 4; \ | 172 | uint8_t *dst = outpicref->data[0] + (b * h + j) * outpicref->linesize[0] + w * ch * 4; \ |
| 169 | const int ww = (s->counter[depth - b - 1] / (float)insamples->nb_samples) * (w - 1); \ | 173 | const int ww = (counter[depth - b - 1] / (float)nb_samples) * (w - 1); \ |
| 170 | \ | 174 | \ |
| 171 | for (int i = 0; i < ww; i++) { \ | 175 | for (int i = 0; i < ww; i++) { \ |
| 172 | AV_WN32(&dst[i * 4], color); \ | 176 | AV_WN32(&dst[i * 4], color); \ |
| @@ -177,25 +181,21 @@ static int config_output(AVFilterLink *outlink) · 4 unmodified lines | |||
| 177 | 181 | ||
| 178 | #define DO_TRACE(type, depth, one) \ | 182 | #define DO_TRACE(type, depth, one) \ |
| 179 | for (int ch = 0; ch < inlink->ch_layout.nb_channels; ch++) { \ | 183 | for (int ch = 0; ch < inlink->ch_layout.nb_channels; ch++) { \ |
| 184 | const int nb_samples = insamples->nb_samples; \ | ||
| 180 | const int w = outpicref->width / inlink->ch_layout.nb_channels; \ | 185 | const int w = outpicref->width / inlink->ch_layout.nb_channels; \ |
| 181 | const type *in = (const type *)insamples->extended_data[ch]; \ | 186 | const type *in = (const type *)insamples->extended_data[ch]; \ |
| 187 | uint64_t *counter = s->counter; \ | ||
| 182 | const int wb = w / depth; \ | 188 | const int wb = w / depth; \ |
| 183 | int wv; \ | 189 | int wv; \ |
| 184 | \ | 190 | \ |
| 185 | memset(s->counter, 0, sizeof(s->counter)); \ | 191 | BITCOUNTER(type, depth, one) \ |
| 186 | for (int i = 0; i < insamples->nb_samples; i++) { \ | ||
| 187 | for (int j = 0; j < depth; j++) { \ | ||
| 188 | if (in[i] & (one << j)) \ | ||
| 189 | s->counter[j]++; \ | ||
| 190 | } \ | ||
| 191 | } \ | ||
| 192 | \ | 192 | \ |
| 193 | for (int b = 0; b < depth; b++) { \ | 193 | for (int b = 0; b < depth; b++) { \ |
| 194 | uint8_t colors[4]; \ | 194 | uint8_t colors[4]; \ |
| 195 | uint32_t color; \ | 195 | uint32_t color; \ |
| 196 | uint8_t *dst = outpicref->data[0] + w * ch * 4 + wb * b * 4 + \ | 196 | uint8_t *dst = outpicref->data[0] + w * ch * 4 + wb * b * 4 + \ |
| 197 | s->current_vpos * outpicref->linesize[0]; \ | 197 | s->current_vpos * outpicref->linesize[0]; \ |
| 198 | wv = (s->counter[depth - b - 1] * 255) / insamples->nb_samples; \ | 198 | wv = (counter[depth - b - 1] * 255) / nb_samples; \ |
| 199 | colors[0] = (wv * s->fg[ch * 4 + 0] + 127) / 255; \ | 199 | colors[0] = (wv * s->fg[ch * 4 + 0] + 127) / 255; \ |
| 200 | colors[1] = (wv * s->fg[ch * 4 + 1] + 127) / 255; \ | 200 | colors[1] = (wv * s->fg[ch * 4 + 1] + 127) / 255; \ |
| 201 | colors[2] = (wv * s->fg[ch * 4 + 2] + 127) / 255; \ | 201 | colors[2] = (wv * s->fg[ch * 4 + 2] + 127) / 255; \ |