small optimizations

Add some SPA_LIKELY
Enable FASTPATH by default
This commit is contained in:
Wim Taymans 2020-03-18 15:43:29 +01:00
parent 57f84ae5ae
commit 8a2af908a7
11 changed files with 55 additions and 44 deletions

View file

@ -60,7 +60,7 @@ if cc.get_id() == 'gcc'
'-Wold-style-declaration', '-Wold-style-declaration',
'-Wvariadic-macros', '-Wvariadic-macros',
# '-DSPA_DEBUG_MEMCPY', # '-DSPA_DEBUG_MEMCPY',
# '-DFASTPATH', '-DFASTPATH',
language : 'c') language : 'c')
endif endif

View file

@ -640,7 +640,7 @@ static int follower_ready(void *data, int status)
{ {
struct impl *this = data; struct impl *this = data;
spa_log_trace(this->log, NAME " %p: ready %d", this, status); spa_log_trace_fp(this->log, NAME " %p: ready %d", this, status);
this->master = true; this->master = true;

View file

@ -1072,8 +1072,10 @@ static int impl_node_process(void *object)
ready = 0; ready = 0;
for (i = 0; i < this->n_nodes; i++) { for (i = 0; i < this->n_nodes; i++) {
r = spa_node_process(this->nodes[i]); r = spa_node_process(this->nodes[i]);
spa_log_trace_fp(this->log, NAME " %p: process %d %d: %s", spa_log_trace_fp(this->log, NAME " %p: process %d %d: %s",
this, i, r, r < 0 ? spa_strerror(r) : "ok"); this, i, r, r < 0 ? spa_strerror(r) : "ok");
if (SPA_UNLIKELY(r < 0)) if (SPA_UNLIKELY(r < 0))
return r; return r;

View file

@ -860,22 +860,22 @@ static int impl_node_process(void *object)
spa_log_trace_fp(this->log, NAME " %p: status %d %d", this, inio->status, outio->status); spa_log_trace_fp(this->log, NAME " %p: status %d %d", this, inio->status, outio->status);
if (outio->status == SPA_STATUS_HAVE_DATA) if (SPA_UNLIKELY(outio->status == SPA_STATUS_HAVE_DATA))
goto done; return SPA_STATUS_HAVE_DATA;
if (inio->status != SPA_STATUS_HAVE_DATA) if (SPA_UNLIKELY(inio->status != SPA_STATUS_HAVE_DATA))
return SPA_STATUS_NEED_DATA; return SPA_STATUS_NEED_DATA;
/* recycle */ /* recycle */
if (outio->buffer_id < outport->n_buffers) { if (SPA_LIKELY(outio->buffer_id < outport->n_buffers)) {
recycle_buffer(this, outio->buffer_id); recycle_buffer(this, outio->buffer_id);
outio->buffer_id = SPA_ID_INVALID; outio->buffer_id = SPA_ID_INVALID;
} }
if (inio->buffer_id >= inport->n_buffers) if (SPA_UNLIKELY(inio->buffer_id >= inport->n_buffers))
return inio->status = -EINVAL; return inio->status = -EINVAL;
if ((dbuf = dequeue_buffer(this, outport)) == NULL) if (SPA_UNLIKELY((dbuf = dequeue_buffer(this, outport)) == NULL))
return outio->status = -EPIPE; return outio->status = -EPIPE;
sbuf = &inport->buffers[inio->buffer_id]; sbuf = &inport->buffers[inio->buffer_id];
@ -911,7 +911,6 @@ static int impl_node_process(void *object)
inio->status = SPA_STATUS_NEED_DATA; inio->status = SPA_STATUS_NEED_DATA;
done:
return SPA_STATUS_HAVE_DATA | SPA_STATUS_NEED_DATA; return SPA_STATUS_HAVE_DATA | SPA_STATUS_NEED_DATA;
} }

View file

@ -817,7 +817,6 @@ static int impl_node_process(void *object)
const void **src_datas; const void **src_datas;
void **dst_datas; void **dst_datas;
uint32_t i, n_src_datas, n_dst_datas; uint32_t i, n_src_datas, n_dst_datas;
int res = 0;
uint32_t n_samples, size, maxsize, offs; uint32_t n_samples, size, maxsize, offs;
spa_return_val_if_fail(this != NULL, -EINVAL); spa_return_val_if_fail(this != NULL, -EINVAL);
@ -837,19 +836,19 @@ static int impl_node_process(void *object)
inio, inio->status, inio->buffer_id, inio, inio->status, inio->buffer_id,
outio, outio->status, outio->buffer_id); outio, outio->status, outio->buffer_id);
if (outio->status == SPA_STATUS_HAVE_DATA) if (SPA_UNLIKELY(outio->status == SPA_STATUS_HAVE_DATA))
return inio->status | outio->status; return inio->status | outio->status;
if (outio->buffer_id < outport->n_buffers) { if (SPA_LIKELY(outio->buffer_id < outport->n_buffers)) {
recycle_buffer(this, outport, outio->buffer_id); recycle_buffer(this, outport, outio->buffer_id);
outio->buffer_id = SPA_ID_INVALID; outio->buffer_id = SPA_ID_INVALID;
} }
if (inio->status != SPA_STATUS_HAVE_DATA) if (SPA_UNLIKELY(inio->status != SPA_STATUS_HAVE_DATA))
return SPA_STATUS_NEED_DATA; return SPA_STATUS_NEED_DATA;
if (inio->buffer_id >= inport->n_buffers) if (SPA_UNLIKELY(inio->buffer_id >= inport->n_buffers))
return inio->status = -EINVAL; return inio->status = -EINVAL;
if ((outbuf = dequeue_buffer(this, outport)) == NULL) if (SPA_UNLIKELY((outbuf = dequeue_buffer(this, outport)) == NULL))
return outio->status = -EPIPE; return outio->status = -EPIPE;
inbuf = &inport->buffers[inio->buffer_id]; inbuf = &inport->buffers[inio->buffer_id];
@ -891,13 +890,11 @@ static int impl_node_process(void *object)
convert_process(&this->conv, dst_datas, src_datas, n_samples); convert_process(&this->conv, dst_datas, src_datas, n_samples);
inio->status = SPA_STATUS_NEED_DATA; inio->status = SPA_STATUS_NEED_DATA;
res |= SPA_STATUS_NEED_DATA;
outio->status = SPA_STATUS_HAVE_DATA; outio->status = SPA_STATUS_HAVE_DATA;
outio->buffer_id = outbuf->id; outio->buffer_id = outbuf->id;
res |= SPA_STATUS_HAVE_DATA;
return res; return SPA_STATUS_NEED_DATA | SPA_STATUS_HAVE_DATA;
} }
static const struct spa_node_methods impl_node = { static const struct spa_node_methods impl_node = {

View file

@ -951,7 +951,7 @@ static int impl_node_process(void *object)
uint32_t n_src_datas, n_dst_datas; uint32_t n_src_datas, n_dst_datas;
const void **src_datas; const void **src_datas;
void **dst_datas; void **dst_datas;
int res = 0; int res;
spa_return_val_if_fail(this != NULL, -EINVAL); spa_return_val_if_fail(this != NULL, -EINVAL);

View file

@ -98,6 +98,9 @@ static void impl_native_update_rate(struct resample *r, double rate)
struct native_data *data = r->data; struct native_data *data = r->data;
uint32_t in_rate, out_rate, phase, gcd, old_out_rate; uint32_t in_rate, out_rate, phase, gcd, old_out_rate;
if (SPA_LIKELY(data->rate == rate))
return;
old_out_rate = data->out_rate; old_out_rate = data->out_rate;
in_rate = r->i_rate / rate; in_rate = r->i_rate / rate;
out_rate = r->o_rate; out_rate = r->o_rate;
@ -165,9 +168,9 @@ static void impl_native_process(struct resample *r,
hist = data->hist; hist = data->hist;
refill = 0; refill = 0;
if (hist) { if (SPA_LIKELY(hist)) {
/* first work on the history if any. */ /* first work on the history if any. */
if (hist < n_taps) { if (SPA_UNLIKELY(hist < n_taps)) {
/* we need at least n_taps to completely process the /* we need at least n_taps to completely process the
* history before we can work on the new input. When * history before we can work on the new input. When
* we have less, refill the history. */ * we have less, refill the history. */
@ -175,7 +178,7 @@ static void impl_native_process(struct resample *r,
for (c = 0; c < r->channels; c++) for (c = 0; c < r->channels; c++)
spa_memcpy(&history[c][hist], s[c], refill * sizeof(float)); spa_memcpy(&history[c][hist], s[c], refill * sizeof(float));
if (hist + refill < n_taps) { if (SPA_UNLIKELY(hist + refill < n_taps)) {
/* not enough in the history, keep the input in /* not enough in the history, keep the input in
* the history and produce no output */ * the history and produce no output */
data->hist = hist + refill; data->hist = hist + refill;
@ -195,12 +198,13 @@ static void impl_native_process(struct resample *r,
out = in = 0; out = in = 0;
} }
if (in >= hist) { if (SPA_LIKELY(in >= hist)) {
int skip = in - hist; int skip = in - hist;
/* we are past the history and can now work on the new /* we are past the history and can now work on the new
* input data */ * input data */
in = *in_len - skip; in = *in_len - skip;
data->func(r, src, skip, &in, dst, out, out_len); data->func(r, src, skip, &in, dst, out, out_len);
spa_log_trace_fp(r->log, "native %p: in:%d/%d out %d/%d", spa_log_trace_fp(r->log, "native %p: in:%d/%d out %d/%d",
r, *in_len, in, *out_len, out); r, *in_len, in, *out_len, out);

View file

@ -51,7 +51,7 @@ static void impl_peaks_process(struct resample *r,
struct peaks_data *pd = r->data; struct peaks_data *pd = r->data;
uint32_t c, i, o, end, chunk, o_count, i_count; uint32_t c, i, o, end, chunk, o_count, i_count;
if (r->channels == 0) if (SPA_UNLIKELY(r->channels == 0))
return; return;
for (c = 0; c < r->channels; c++) { for (c = 0; c < r->channels; c++) {

View file

@ -713,7 +713,10 @@ static int impl_node_process(void *object)
struct spa_io_buffers *outio, *inio; struct spa_io_buffers *outio, *inio;
struct buffer *sbuf, *dbuf; struct buffer *sbuf, *dbuf;
struct spa_buffer *sb, *db; struct spa_buffer *sb, *db;
uint32_t i, size, in_len, out_len, pin_len, pout_len, maxsize, max; uint32_t i, size, in_len, out_len, maxsize, max;
#ifndef FASTPATH
uint32_t pin_len, pout_len;
#endif
int res = 0; int res = 0;
const void **src_datas; const void **src_datas;
void **dst_datas; void **dst_datas;
@ -734,22 +737,22 @@ static int impl_node_process(void *object)
spa_log_trace_fp(this->log, NAME " %p: status %d %d %d", spa_log_trace_fp(this->log, NAME " %p: status %d %d %d",
this, inio->status, outio->status, inio->buffer_id); this, inio->status, outio->status, inio->buffer_id);
if (outio->status == SPA_STATUS_HAVE_DATA) if (SPA_UNLIKELY(outio->status == SPA_STATUS_HAVE_DATA))
return SPA_STATUS_HAVE_DATA; return SPA_STATUS_HAVE_DATA;
if (inio->status != SPA_STATUS_HAVE_DATA) if (SPA_UNLIKELY(inio->status != SPA_STATUS_HAVE_DATA))
return SPA_STATUS_NEED_DATA; return SPA_STATUS_NEED_DATA;
/* recycle */ /* recycle */
if (outio->buffer_id < outport->n_buffers) { if (SPA_LIKELY(outio->buffer_id < outport->n_buffers)) {
recycle_buffer(this, outio->buffer_id); recycle_buffer(this, outio->buffer_id);
outio->buffer_id = SPA_ID_INVALID; outio->buffer_id = SPA_ID_INVALID;
} }
if (inio->buffer_id >= inport->n_buffers) if (SPA_UNLIKELY(inio->buffer_id >= inport->n_buffers))
return inio->status = -EINVAL; return inio->status = -EINVAL;
if ((dbuf = peek_buffer(this, outport)) == NULL) if (SPA_UNLIKELY((dbuf = peek_buffer(this, outport)) == NULL))
return outio->status = -EPIPE; return outio->status = -EPIPE;
sbuf = &inport->buffers[inio->buffer_id]; sbuf = &inport->buffers[inio->buffer_id];
@ -760,11 +763,10 @@ static int impl_node_process(void *object)
size = sb->datas[0].chunk->size; size = sb->datas[0].chunk->size;
maxsize = db->datas[0].maxsize; maxsize = db->datas[0].maxsize;
if (this->io_position) { if (SPA_LIKELY(this->io_position))
max = this->io_position->clock.duration; max = this->io_position->clock.duration;
} else { else
max = maxsize / sizeof(float); max = maxsize / sizeof(float);
}
switch (this->mode) { switch (this->mode) {
case MODE_SPLIT: case MODE_SPLIT:
@ -788,9 +790,6 @@ static int impl_node_process(void *object)
in_len = (size - inport->offset) / sizeof(float); in_len = (size - inport->offset) / sizeof(float);
out_len = (maxsize - outport->offset) / sizeof(float); out_len = (maxsize - outport->offset) / sizeof(float);
pin_len = in_len;
pout_len = out_len;
src_datas = alloca(sizeof(void*) * this->resample.channels); src_datas = alloca(sizeof(void*) * this->resample.channels);
dst_datas = alloca(sizeof(void*) * this->resample.channels); dst_datas = alloca(sizeof(void*) * this->resample.channels);
@ -799,12 +798,19 @@ static int impl_node_process(void *object)
for (i = 0; i < db->n_datas; i++) for (i = 0; i < db->n_datas; i++)
dst_datas[i] = SPA_MEMBER(db->datas[i].data, outport->offset, void); dst_datas[i] = SPA_MEMBER(db->datas[i].data, outport->offset, void);
#ifndef FASTPATH
pin_len = in_len;
pout_len = out_len;
#endif
resample_process(&this->resample, src_datas, &in_len, dst_datas, &out_len); resample_process(&this->resample, src_datas, &in_len, dst_datas, &out_len);
#ifndef FASTPATH
spa_log_trace_fp(this->log, NAME " %p: in %d/%d %zd %d out %d/%d %zd %d max:%d", spa_log_trace_fp(this->log, NAME " %p: in %d/%d %zd %d out %d/%d %zd %d max:%d",
this, pin_len, in_len, size / sizeof(float), inport->offset, this, pin_len, in_len, size / sizeof(float), inport->offset,
pout_len, out_len, maxsize / sizeof(float), outport->offset, pout_len, out_len, maxsize / sizeof(float), outport->offset,
max); max);
#endif
for (i = 0; i < db->n_datas; i++) { for (i = 0; i < db->n_datas; i++) {
db->datas[i].chunk->size = outport->offset + (out_len * sizeof(float)); db->datas[i].chunk->size = outport->offset + (out_len * sizeof(float));

View file

@ -859,9 +859,10 @@ static int impl_node_process(void *object)
spa_log_trace_fp(this->log, NAME " %p: status %p %d %d", this, spa_log_trace_fp(this->log, NAME " %p: status %p %d %d", this,
inio, inio->status, inio->buffer_id); inio, inio->status, inio->buffer_id);
if (inio->status != SPA_STATUS_HAVE_DATA) if (SPA_UNLIKELY(inio->status != SPA_STATUS_HAVE_DATA))
return SPA_STATUS_NEED_DATA; return SPA_STATUS_NEED_DATA;
if (inio->buffer_id >= inport->n_buffers)
if (SPA_UNLIKELY(inio->buffer_id >= inport->n_buffers))
return inio->status = -EINVAL; return inio->status = -EINVAL;
sbuf = &inport->buffers[inio->buffer_id]; sbuf = &inport->buffers[inio->buffer_id];
@ -885,23 +886,23 @@ static int impl_node_process(void *object)
struct port *outport = GET_OUT_PORT(this, i); struct port *outport = GET_OUT_PORT(this, i);
struct spa_io_buffers *outio; struct spa_io_buffers *outio;
if ((outio = outport->io) == NULL) if (SPA_UNLIKELY((outio = outport->io) == NULL))
goto empty; goto empty;
spa_log_trace_fp(this->log, NAME " %p: %d %p %d %d %d", this, i, spa_log_trace_fp(this->log, NAME " %p: %d %p %d %d %d", this, i,
outio, outio->status, outio->buffer_id, outport->stride); outio, outio->status, outio->buffer_id, outport->stride);
if (outio->status == SPA_STATUS_HAVE_DATA) { if (SPA_UNLIKELY(outio->status == SPA_STATUS_HAVE_DATA)) {
res |= SPA_STATUS_HAVE_DATA; res |= SPA_STATUS_HAVE_DATA;
goto empty; goto empty;
} }
if (outio->buffer_id < outport->n_buffers) { if (SPA_LIKELY(outio->buffer_id < outport->n_buffers)) {
queue_buffer(this, outport, outio->buffer_id); queue_buffer(this, outport, outio->buffer_id);
outio->buffer_id = SPA_ID_INVALID; outio->buffer_id = SPA_ID_INVALID;
} }
if ((dbuf = dequeue_buffer(this, outport)) == NULL) { if (SPA_UNLIKELY((dbuf = dequeue_buffer(this, outport)) == NULL)) {
outio->status = -EPIPE; outio->status = -EPIPE;
empty: empty:
spa_log_trace_fp(this->log, NAME" %p: %d skip output", this, i); spa_log_trace_fp(this->log, NAME" %p: %d skip output", this, i);

View file

@ -877,11 +877,13 @@ static int impl_node_process(void *object)
spa_log_trace_fp(this->log, "%p: send process driver:%p", this, impl->this.node->driver_node); spa_log_trace_fp(this->log, "%p: send process driver:%p", this, impl->this.node->driver_node);
spa_system_clock_gettime(this->data_system, CLOCK_MONOTONIC, &ts); if (SPA_UNLIKELY(spa_system_clock_gettime(this->data_system, CLOCK_MONOTONIC, &ts) < 0))
spa_zero(ts);
n->rt.activation->status = PW_NODE_ACTIVATION_TRIGGERED; n->rt.activation->status = PW_NODE_ACTIVATION_TRIGGERED;
n->rt.activation->signal_time = SPA_TIMESPEC_TO_NSEC(&ts); n->rt.activation->signal_time = SPA_TIMESPEC_TO_NSEC(&ts);
if (spa_system_eventfd_write(this->data_system, this->writefd, 1) < 0) if (SPA_UNLIKELY(spa_system_eventfd_write(this->data_system, this->writefd, 1) < 0))
spa_log_warn(this->log, NAME" %p: error %m", this); spa_log_warn(this->log, NAME" %p: error %m", this);
return SPA_STATUS_OK; return SPA_STATUS_OK;