1
0
mirror of https://github.com/RPCS3/soundtouch.git synced 2024-11-09 12:22:51 +01:00

- OpenMP parallel processing disabled by default; can be enabled in compile-time

- Android: Workaround for threading issue to enable OpenMP parallel processing in Android
This commit is contained in:
oparviai 2015-05-15 10:22:36 +00:00
parent 92973bc18e
commit d44723ea57
7 changed files with 96 additions and 18 deletions

View File

@ -85,8 +85,8 @@ AC_ARG_ENABLE(integer-samples,
AC_ARG_ENABLE(openmp,
[AC_HELP_STRING([--enable-openmp],
[use parallel multicore calculation through OpenMP [default=yes]])],,
[enable_openmp=yes])
[use parallel multicore calculation through OpenMP [default=no]])],,
[enable_openmp=no])
# Let the user enable/disable the x86 optimizations.
# Useful when compiling on non-x86 architectures.

View File

@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="gen"/>
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="gen"/>
<classpathentry kind="output" path="bin/classes"/>
</classpath>

View File

@ -36,10 +36,16 @@ LOCAL_SHARED_LIBRARIES += -lgcc
LOCAL_LDLIBS += -llog
# for native asset manager
#LOCAL_LDLIBS += -landroid
# don't export all symbols
#
# in ARM-only environment could add "-marm" switch to force arm instruction set instead
# of thumb for improved calculation performance.
LOCAL_CFLAGS += -fvisibility=hidden -I ../../../include -fdata-sections -ffunction-sections
# Custom Flags:
# -fvisibility=hidden : don't export all symbols
# -fopenmp : enable these flags to allow using OpenMP for parallel computation
LOCAL_CFLAGS += -fvisibility=hidden -I ../../../include -fdata-sections -ffunction-sections #-fopenmp
#LOCAL_LDFLAGS += -fopenmp
# Use ARM instruction set instead of Thumb for improved calculation performance in ARM CPUs
LOCAL_ARM_MODE := arm
include $(BUILD_SHARED_LIBRARY)

View File

@ -6,4 +6,5 @@
APP_ABI := all #armeabi-v7a armeabi
APP_OPTIM := release
APP_STL := stlport_static
APP_CPPFLAGS := -fexceptions
APP_CPPFLAGS := -fexceptions # -D SOUNDTOUCH_DISABLE_X86_OPTIMIZATIONS

View File

@ -46,6 +46,54 @@ static void _setErrmsg(const char *msg)
}
#ifdef _OPENMP
#include <pthread.h>
extern pthread_key_t gomp_tls_key;
static void * _p_gomp_tls = NULL;
/// Function to initialize threading for OpenMP.
///
/// This is a workaround for bug in Android NDK v10 regarding OpenMP: OpenMP works only if
/// called from the Android App main thread because in the main thread the gomp_tls storage is
/// properly set, however, Android does not properly initialize gomp_tls storage for other threads.
/// Thus if OpenMP routines are invoked from some other thread than the main thread,
/// the OpenMP routine will crash the application due to NULL pointer access on uninitialized storage.
///
/// This workaround stores the gomp_tls storage from main thread, and copies to other threads.
/// In order this to work, the Application main thread needws to call at least "getVersionString"
/// routine.
static int _init_threading(bool warn)
{
void *ptr = pthread_getspecific(gomp_tls_key);
LOGV("JNI thread-specific TLS storage %ld", (long)ptr);
if (ptr == NULL)
{
LOGV("JNI set missing TLS storage to %ld", (long)_p_gomp_tls);
pthread_setspecific(gomp_tls_key, _p_gomp_tls);
}
else
{
LOGV("JNI store this TLS storage");
_p_gomp_tls = ptr;
}
// Where critical, show warning if storage still not properly initialized
if ((warn) && (_p_gomp_tls == NULL))
{
_setErrmsg("Error - OpenMP threading not properly initialized: Call SoundTouch.getVersionString() from the App main thread!");
return -1;
}
return 0;
}
#else
static int _init_threading(bool warn)
{
// do nothing if not OpenMP build
return 0;
}
#endif
// Processes the sound file
static void _processFile(SoundTouch *pSoundTouch, const char *inFileName, const char *outFileName)
@ -118,6 +166,17 @@ extern "C" DLL_PUBLIC jstring Java_net_surina_soundtouch_SoundTouch_getVersionSt
// Call example SoundTouch routine
verStr = SoundTouch::getVersionString();
/// gomp_tls storage bug workaround - see comments in _init_threading() function!
_init_threading(false);
int threads = 0;
#pragma omp parallel
{
#pragma omp atomic
threads ++;
}
LOGV("JNI thread count %d", threads);
// return version as string
return env->NewStringUTF(verStr);
}
@ -176,6 +235,9 @@ extern "C" DLL_PUBLIC int Java_net_surina_soundtouch_SoundTouch_processFile(JNIE
LOGV("JNI process file %s", inputFile);
/// gomp_tls storage bug workaround - see comments in _init_threading() function!
if (_init_threading(true)) return -1;
try
{
_processFile(ptr, inputFile, outputFile);

View File

@ -25,7 +25,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="5"
android:inputType="numberDecimal"
android:inputType="text"
android:text="100" >
</EditText>
</TableRow>
@ -46,8 +46,8 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="5"
android:inputType="numberSigned"
android:text="0" >
android:inputType="text"
android:text="-0.318" >
</EditText>
</TableRow>
</TableLayout>

View File

@ -146,11 +146,10 @@ public class ExampleActivity extends Activity implements OnClickListener
}
/// Processing routine
@Override
protected Long doInBackground(Parameters... aparams)
/// Function that does the SoundTouch processing
public final long doSoundTouchProcessing(Parameters params)
{
Parameters params = aparams[0];
SoundTouch st = new SoundTouch();
st.setTempo(params.tempo);
@ -177,6 +176,15 @@ public class ExampleActivity extends Activity implements OnClickListener
}
return 0L;
}
/// Overloaded function that get called by the system to perform the background processing
@Override
protected Long doInBackground(Parameters... aparams)
{
return doSoundTouchProcessing(aparams[0]);
}
}
@ -202,8 +210,9 @@ public class ExampleActivity extends Activity implements OnClickListener
Toast.makeText(this, "Starting to process file " + params.inFileName + "...", Toast.LENGTH_SHORT).show();
// start processing task in background
// start SoundTouch processing in a background thread
task.execute(params);
// task.doSoundTouchProcessing(params); // this would run processing in main thread
}
catch (Exception exp)