Tweaked the number of extractor threads. Also added a simple benchmark function (disabled in regular builds).

This commit is contained in:
LoRd_MuldeR 2013-11-01 19:34:27 +01:00
parent d888855e4a
commit d2a7406fc3
6 changed files with 119 additions and 32 deletions

View File

@ -34,8 +34,8 @@
#define VER_LAMEXP_MINOR_HI 0 #define VER_LAMEXP_MINOR_HI 0
#define VER_LAMEXP_MINOR_LO 9 #define VER_LAMEXP_MINOR_LO 9
#define VER_LAMEXP_TYPE Alpha #define VER_LAMEXP_TYPE Alpha
#define VER_LAMEXP_PATCH 6 #define VER_LAMEXP_PATCH 7
#define VER_LAMEXP_BUILD 1444 #define VER_LAMEXP_BUILD 1447
#define VER_LAMEXP_CONFG 1348 #define VER_LAMEXP_CONFG 1348
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////

View File

@ -131,7 +131,7 @@ void SplashScreen::showSplash(QThread *thread)
//Start the thread //Start the thread
splashScreen->m_timer->start(FADE_DELAY); splashScreen->m_timer->start(FADE_DELAY);
QTimer::singleShot(3*60*1000, splashScreen->m_loop, SLOT(quit())); QTimer::singleShot(8*60*1000, splashScreen->m_loop, SLOT(quit()));
QTimer::singleShot(0, thread, SLOT(start())); QTimer::singleShot(0, thread, SLOT(start()));
//Start event handling! //Start event handling!

View File

@ -3179,6 +3179,25 @@ void lamexp_fatal_exit(const wchar_t* exitMessage, const wchar_t* errorBoxMessag
Sleep(INFINITE); Sleep(INFINITE);
} }
/*
* Free all registered tools (final clean-up)
*/
void lamexp_clean_all_tools(void)
{
if(g_lamexp_tools.registry)
{
QStringList keys = g_lamexp_tools.registry->keys();
for(int i = 0; i < keys.count(); i++)
{
LockedFile *lf = g_lamexp_tools.registry->take(keys.at(i));
LAMEXP_DELETE(lf);
}
g_lamexp_tools.registry->clear();
g_lamexp_tools.versions->clear();
g_lamexp_tools.tags->clear();
}
}
/* /*
* Finalization function (final clean-up) * Finalization function (final clean-up)
*/ */
@ -3189,11 +3208,7 @@ void lamexp_finalization(void)
//Free all tools //Free all tools
if(g_lamexp_tools.registry) if(g_lamexp_tools.registry)
{ {
QStringList keys = g_lamexp_tools.registry->keys(); lamexp_clean_all_tools();
for(int i = 0; i < keys.count(); i++)
{
LAMEXP_DELETE((*g_lamexp_tools.registry)[keys.at(i)]);
}
LAMEXP_DELETE(g_lamexp_tools.registry); LAMEXP_DELETE(g_lamexp_tools.registry);
LAMEXP_DELETE(g_lamexp_tools.versions); LAMEXP_DELETE(g_lamexp_tools.versions);
LAMEXP_DELETE(g_lamexp_tools.tags); LAMEXP_DELETE(g_lamexp_tools.tags);

View File

@ -76,18 +76,12 @@ FileAnalyzer::FileAnalyzer(const QStringList &inputFiles)
FileAnalyzer::~FileAnalyzer(void) FileAnalyzer::~FileAnalyzer(void)
{ {
if(m_templateFile)
{
QString templatePath = m_templateFile->filePath();
LAMEXP_DELETE(m_templateFile);
if(QFile::exists(templatePath)) QFile::remove(templatePath);
}
if(!m_pool->waitForDone(2500)) if(!m_pool->waitForDone(2500))
{ {
qWarning("There are still running tasks in the thread pool!"); qWarning("There are still running tasks in the thread pool!");
} }
LAMEXP_DELETE(m_templateFile);
LAMEXP_DELETE(m_pool); LAMEXP_DELETE(m_pool);
LAMEXP_DELETE(m_timer); LAMEXP_DELETE(m_timer);
} }
@ -351,7 +345,7 @@ bool FileAnalyzer::createTemplate(void)
try try
{ {
m_templateFile = new LockedFile(templatePath); m_templateFile = new LockedFile(templatePath, true);
} }
catch(const std::exception &error) catch(const std::exception &error)
{ {

View File

@ -45,6 +45,10 @@
/* constants */ /* constants */
static const double g_allowedExtractDelay = 12.0; static const double g_allowedExtractDelay = 12.0;
static const size_t BUFF_SIZE = 512; static const size_t BUFF_SIZE = 512;
static const size_t EXPECTED_TOOL_COUNT = 27;
/* benchmark */
#undef ENABLE_BENCHMARK
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// ExtractorTask class // ExtractorTask class
@ -188,7 +192,34 @@ InitializationThread::InitializationThread(const lamexp_cpu_t *cpuFeatures)
// Thread Main // Thread Main
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void InitializationThread::run() #ifdef ENABLE_BENCHMARK
#define DO_INIT_FUNCT runBenchmark
void lamexp_clean_all_tools(void);
#else //ENABLE_BENCHMARK
#define DO_INIT_FUNCT doInit
#endif //ENABLE_BENCHMARK
void InitializationThread::run(void)
{
try
{
DO_INIT_FUNCT();
}
catch(const std::exception &error)
{
fflush(stdout); fflush(stderr);
fprintf(stderr, "\nGURU MEDITATION !!!\n\nException error:\n%s\n", error.what());
lamexp_fatal_exit(L"Unhandeled C++ exception error, application will exit!");
}
catch(...)
{
fflush(stdout); fflush(stderr);
fprintf(stderr, "\nGURU MEDITATION !!!\n\nUnknown exception error!\n");
lamexp_fatal_exit(L"Unhandeled C++ exception error, application will exit!");
}
}
double InitializationThread::doInit(const size_t threadCount)
{ {
m_bSuccess = false; m_bSuccess = false;
delay(); delay();
@ -255,11 +286,7 @@ void InitializationThread::run()
QDir appDir = QDir(QCoreApplication::applicationDirPath()).canonicalPath(); QDir appDir = QDir(QCoreApplication::applicationDirPath()).canonicalPath();
QThreadPool *pool = new QThreadPool(); QThreadPool *pool = new QThreadPool();
const int idealThreadCount = QThread::idealThreadCount(); pool->setMaxThreadCount((threadCount > 0) ? threadCount : qBound(2U, (m_cpuFeatures.count * 2U), EXPECTED_TOOL_COUNT));
if(idealThreadCount > 0)
{
pool->setMaxThreadCount(idealThreadCount * 2);
}
LockedFile::selfTest(); LockedFile::selfTest();
ExtractorTask::clearFlags(); ExtractorTask::clearFlags();
@ -279,7 +306,7 @@ void InitializationThread::run()
if(toolHash.size() != 96) if(toolHash.size() != 96)
{ {
qFatal("The checksum for \"%s\" has an invalid size!", QUTF8(toolName)); qFatal("The checksum for \"%s\" has an invalid size!", QUTF8(toolName));
return; return -1.0;
} }
QResource *resource = new QResource(QString(":/tools/%1").arg(toolName)); QResource *resource = new QResource(QString(":/tools/%1").arg(toolName));
@ -287,7 +314,7 @@ void InitializationThread::run()
{ {
LAMEXP_DELETE(resource); LAMEXP_DELETE(resource);
qFatal("The resource for \"%s\" could not be found!", QUTF8(toolName)); qFatal("The resource for \"%s\" could not be found!", QUTF8(toolName));
return; return -1.0;
} }
if(cpuType & cpuSupport) if(cpuType & cpuSupport)
@ -318,10 +345,10 @@ void InitializationThread::run()
if(ExtractorTask::getErrMsg(errorMsg, BUFF_SIZE)) if(ExtractorTask::getErrMsg(errorMsg, BUFF_SIZE))
{ {
qFatal("At least one of the required tools could not be initialized:\n%s", errorMsg); qFatal("At least one of the required tools could not be initialized:\n%s", errorMsg);
return; return -1.0;
} }
qFatal("At least one of the required tools could not be initialized!"); qFatal("At least one of the required tools could not be initialized!");
return; return -1.0;
} }
qDebug("All extracted.\n"); qDebug("All extracted.\n");
@ -333,7 +360,7 @@ void InitializationThread::run()
} }
//Check delay //Check delay
double delayExtract = static_cast<double>(timeExtractEnd - timeExtractStart) / static_cast<double>(lamexp_perfcounter_frequ()); const double delayExtract = static_cast<double>(timeExtractEnd - timeExtractStart) / static_cast<double>(lamexp_perfcounter_frequ());
if(delayExtract > g_allowedExtractDelay) if(delayExtract > g_allowedExtractDelay)
{ {
m_slowIndicator = true; m_slowIndicator = true;
@ -353,8 +380,55 @@ void InitializationThread::run()
initFhgAac(); initFhgAac();
initQAac(); initQAac();
delay();
m_bSuccess = true; m_bSuccess = true;
delay();
return delayExtract;
}
void InitializationThread::runBenchmark(void)
{
#ifdef ENABLE_BENCHMARK
static const size_t nLoops = 5;
const size_t maxThreads = (5 * m_cpuFeatures.count);
QMap<size_t, double> results;
for(size_t c = 1; c <= maxThreads; c++)
{
double delayAcc = 0.0;
for(size_t i = 0; i < nLoops; i++)
{
delayAcc += doInit(c);
lamexp_clean_all_tools();
}
results.insert(c, (delayAcc / double(nLoops)));
}
qWarning("\n----------------------------------------------");
qWarning("Benchmark Results:");
qWarning("----------------------------------------------");
double bestTime = DBL_MAX; size_t bestVal = 0;
QList<size_t> keys = results.keys();
for(QList<size_t>::ConstIterator iter = keys.begin(); iter != keys.end(); iter++)
{
const double time = results.value((*iter), DBL_MAX);
qWarning("%02u -> %7.4f", (*iter), time);
if(time < bestTime)
{
bestTime = time;
bestVal = (*iter);
}
}
qWarning("----------------------------------------------");
qWarning("BEST: %u of %u (factor: %7.4f)", bestVal, m_cpuFeatures.count, (double(bestVal) / double(m_cpuFeatures.count)));
qWarning("----------------------------------------------\n");
qFatal("Benchmark complete. Thanks and bye bye!");
#else //ENABLE_BENCHMARK
THROW("Sorry, the benchmark is *not* available in this build!");
#endif //ENABLE_BENCHMARK
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
@ -765,7 +839,6 @@ void InitializationThread::initQAac(void)
void InitializationThread::selfTest(void) void InitializationThread::selfTest(void)
{ {
static const unsigned int expcetedCount = 27;
const unsigned int cpu[4] = {CPU_TYPE_X86_GEN, CPU_TYPE_X86_SSE, CPU_TYPE_X64_GEN, CPU_TYPE_X64_SSE}; const unsigned int cpu[4] = {CPU_TYPE_X86_GEN, CPU_TYPE_X86_SSE, CPU_TYPE_X64_GEN, CPU_TYPE_X64_SSE};
LockedFile::selfTest(); LockedFile::selfTest();
@ -815,7 +888,7 @@ void InitializationThread::selfTest(void)
qFatal("Inconsistent checksum data detected. Take care!"); qFatal("Inconsistent checksum data detected. Take care!");
} }
} }
if(n != expcetedCount) if(n != EXPECTED_TOOL_COUNT)
{ {
qFatal("Tool count mismatch for CPU type %u !!!", cpu[4]); qFatal("Tool count mismatch for CPU type %u !!!", cpu[4]);
} }
@ -827,4 +900,4 @@ void InitializationThread::selfTest(void)
// EVENTS // EVENTS
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/*NONE*/ /*NONE*/

View File

@ -35,12 +35,17 @@ class InitializationThread: public QThread
public: public:
InitializationThread(const lamexp_cpu_t *cpuFeatures); InitializationThread(const lamexp_cpu_t *cpuFeatures);
void run();
bool getSuccess(void) { return !isRunning() && m_bSuccess; } bool getSuccess(void) { return !isRunning() && m_bSuccess; }
bool getSlowIndicator(void) { return m_slowIndicator; } bool getSlowIndicator(void) { return m_slowIndicator; }
static void selfTest(void); static void selfTest(void);
protected:
void run(void);
double doInit(const size_t threadCount = 0);
void runBenchmark(void);
private: private:
void delay(void); void delay(void);
void initTranslations(void); void initTranslations(void);