mirror of
https://github.com/ZDoom/fluidsynth.git
synced 2024-11-10 15:01:40 +00:00
Small optimization by not starting threads not likely to be used
This commit is contained in:
parent
5a21df18a6
commit
b86c115898
1 changed files with 29 additions and 8 deletions
|
@ -31,6 +31,10 @@
|
||||||
|
|
||||||
#define ENABLE_MIXER_THREADS 1
|
#define ENABLE_MIXER_THREADS 1
|
||||||
|
|
||||||
|
// If less than x voices, the thread overhead is larger than the gain,
|
||||||
|
// so don't activate the thread(s).
|
||||||
|
#define VOICES_PER_THREAD 8
|
||||||
|
|
||||||
typedef struct _fluid_mixer_buffers_t fluid_mixer_buffers_t;
|
typedef struct _fluid_mixer_buffers_t fluid_mixer_buffers_t;
|
||||||
|
|
||||||
struct _fluid_mixer_buffers_t {
|
struct _fluid_mixer_buffers_t {
|
||||||
|
@ -700,6 +704,7 @@ fluid_mixer_get_mt_rvoice(fluid_rvoice_mixer_t* mixer)
|
||||||
#define THREAD_BUF_PROCESSING 0
|
#define THREAD_BUF_PROCESSING 0
|
||||||
#define THREAD_BUF_VALID 1
|
#define THREAD_BUF_VALID 1
|
||||||
#define THREAD_BUF_NODATA 2
|
#define THREAD_BUF_NODATA 2
|
||||||
|
#define THREAD_BUF_TERMINATE 3
|
||||||
|
|
||||||
/* Core thread function (processes voices in parallel to primary synthesis thread) */
|
/* Core thread function (processes voices in parallel to primary synthesis thread) */
|
||||||
static void
|
static void
|
||||||
|
@ -721,8 +726,12 @@ fluid_mixer_thread_func (void* data)
|
||||||
fluid_cond_mutex_unlock(mixer->thread_ready_m);
|
fluid_cond_mutex_unlock(mixer->thread_ready_m);
|
||||||
|
|
||||||
fluid_cond_mutex_lock(mixer->wakeup_threads_m);
|
fluid_cond_mutex_lock(mixer->wakeup_threads_m);
|
||||||
if (fluid_atomic_int_get(&buffers->ready) != THREAD_BUF_PROCESSING)
|
while (1) {
|
||||||
|
int j = fluid_atomic_int_get(&buffers->ready);
|
||||||
|
if (j == THREAD_BUF_PROCESSING || j == THREAD_BUF_TERMINATE)
|
||||||
|
break;
|
||||||
fluid_cond_wait(mixer->wakeup_threads, mixer->wakeup_threads_m);
|
fluid_cond_wait(mixer->wakeup_threads, mixer->wakeup_threads_m);
|
||||||
|
}
|
||||||
fluid_cond_mutex_unlock(mixer->wakeup_threads_m);
|
fluid_cond_mutex_unlock(mixer->wakeup_threads_m);
|
||||||
|
|
||||||
hasValidData = 0;
|
hasValidData = 0;
|
||||||
|
@ -774,13 +783,13 @@ fluid_mixer_buffers_mix(fluid_mixer_buffers_t* dest, fluid_mixer_buffers_t* src)
|
||||||
* Go through all threads and see if someone is finished for mixing
|
* Go through all threads and see if someone is finished for mixing
|
||||||
*/
|
*/
|
||||||
static FLUID_INLINE int
|
static FLUID_INLINE int
|
||||||
fluid_mixer_mix_in(fluid_rvoice_mixer_t* mixer)
|
fluid_mixer_mix_in(fluid_rvoice_mixer_t* mixer, int extra_threads)
|
||||||
{
|
{
|
||||||
int i, result, hasmixed;
|
int i, result, hasmixed;
|
||||||
do {
|
do {
|
||||||
hasmixed = 0;
|
hasmixed = 0;
|
||||||
result = 0;
|
result = 0;
|
||||||
for (i=0; i < mixer->thread_count; i++) {
|
for (i=0; i < extra_threads; i++) {
|
||||||
int j = fluid_atomic_int_get(&mixer->threads[i].ready);
|
int j = fluid_atomic_int_get(&mixer->threads[i].ready);
|
||||||
switch (j) {
|
switch (j) {
|
||||||
case THREAD_BUF_PROCESSING:
|
case THREAD_BUF_PROCESSING:
|
||||||
|
@ -800,23 +809,33 @@ fluid_mixer_mix_in(fluid_rvoice_mixer_t* mixer)
|
||||||
static void
|
static void
|
||||||
fluid_render_loop_multithread(fluid_rvoice_mixer_t* mixer)
|
fluid_render_loop_multithread(fluid_rvoice_mixer_t* mixer)
|
||||||
{
|
{
|
||||||
int i; //, test=0, waits=0;
|
int i, bufcount;
|
||||||
//int scount = mixer->current_blockcount * FLUID_BUFSIZE;
|
//int scount = mixer->current_blockcount * FLUID_BUFSIZE;
|
||||||
FLUID_DECLARE_VLA(fluid_real_t*, bufs,
|
FLUID_DECLARE_VLA(fluid_real_t*, bufs,
|
||||||
mixer->buffers.buf_count * 2 + mixer->buffers.fx_buf_count * 2);
|
mixer->buffers.buf_count * 2 + mixer->buffers.fx_buf_count * 2);
|
||||||
int bufcount = fluid_mixer_buffers_prepare(&mixer->buffers, bufs);
|
// How many threads should we start this time?
|
||||||
|
int extra_threads = mixer->active_voices / VOICES_PER_THREAD;
|
||||||
|
if (extra_threads > mixer->thread_count)
|
||||||
|
extra_threads = mixer->thread_count;
|
||||||
|
if (extra_threads == 0) {
|
||||||
|
// No extra threads? No thread overhead!
|
||||||
|
fluid_render_loop_singlethread(mixer);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bufcount = fluid_mixer_buffers_prepare(&mixer->buffers, bufs);
|
||||||
|
|
||||||
// Prepare voice list
|
// Prepare voice list
|
||||||
fluid_cond_mutex_lock(mixer->wakeup_threads_m);
|
fluid_cond_mutex_lock(mixer->wakeup_threads_m);
|
||||||
fluid_atomic_int_set(&mixer->current_rvoice, 0);
|
fluid_atomic_int_set(&mixer->current_rvoice, 0);
|
||||||
for (i=0; i < mixer->thread_count && i < (mixer->active_voices-1); i++)
|
for (i=0; i < extra_threads; i++)
|
||||||
fluid_atomic_int_set(&mixer->threads[i].ready, THREAD_BUF_PROCESSING);
|
fluid_atomic_int_set(&mixer->threads[i].ready, THREAD_BUF_PROCESSING);
|
||||||
// Signal threads to wake up
|
// Signal threads to wake up
|
||||||
fluid_cond_broadcast(mixer->wakeup_threads);
|
fluid_cond_broadcast(mixer->wakeup_threads);
|
||||||
fluid_cond_mutex_unlock(mixer->wakeup_threads_m);
|
fluid_cond_mutex_unlock(mixer->wakeup_threads_m);
|
||||||
|
|
||||||
// If thread is finished, mix it in
|
// If thread is finished, mix it in
|
||||||
while (fluid_mixer_mix_in(mixer)) {
|
while (fluid_mixer_mix_in(mixer, extra_threads)) {
|
||||||
// Otherwise get a voice and render it
|
// Otherwise get a voice and render it
|
||||||
fluid_rvoice_t* rvoice = fluid_mixer_get_mt_rvoice(mixer);
|
fluid_rvoice_t* rvoice = fluid_mixer_get_mt_rvoice(mixer);
|
||||||
if (rvoice != NULL) {
|
if (rvoice != NULL) {
|
||||||
|
@ -830,7 +849,7 @@ fluid_render_loop_multithread(fluid_rvoice_mixer_t* mixer)
|
||||||
int is_processing = 0;
|
int is_processing = 0;
|
||||||
//waits++;
|
//waits++;
|
||||||
fluid_cond_mutex_lock(mixer->thread_ready_m);
|
fluid_cond_mutex_lock(mixer->thread_ready_m);
|
||||||
for (i=0; i < mixer->thread_count; i++)
|
for (i=0; i < extra_threads; i++)
|
||||||
if (fluid_atomic_int_get(&mixer->threads[i].ready) ==
|
if (fluid_atomic_int_get(&mixer->threads[i].ready) ==
|
||||||
THREAD_BUF_PROCESSING)
|
THREAD_BUF_PROCESSING)
|
||||||
is_processing = 1;
|
is_processing = 1;
|
||||||
|
@ -862,6 +881,8 @@ fluid_rvoice_mixer_set_threads(fluid_rvoice_mixer_t* mixer, int thread_count,
|
||||||
fluid_atomic_int_set(&mixer->threads_should_terminate, 1);
|
fluid_atomic_int_set(&mixer->threads_should_terminate, 1);
|
||||||
// Signal threads to wake up
|
// Signal threads to wake up
|
||||||
fluid_cond_mutex_lock(mixer->wakeup_threads_m);
|
fluid_cond_mutex_lock(mixer->wakeup_threads_m);
|
||||||
|
for (i=0; i < mixer->thread_count; i++)
|
||||||
|
fluid_atomic_int_set(&mixer->threads[i].ready, THREAD_BUF_TERMINATE);
|
||||||
fluid_cond_broadcast(mixer->wakeup_threads);
|
fluid_cond_broadcast(mixer->wakeup_threads);
|
||||||
fluid_cond_mutex_unlock(mixer->wakeup_threads_m);
|
fluid_cond_mutex_unlock(mixer->wakeup_threads_m);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue