From d2a7406fc341bec92a66b04b9ce43bdfb5056889 Mon Sep 17 00:00:00 2001 From: LoRd_MuldeR Date: Fri, 1 Nov 2013 19:34:27 +0100 Subject: [PATCH] Tweaked the number of extractor threads. Also added a simple benchmark function (disabled in regular builds). --- src/Config.h | 4 +- src/Dialog_SplashScreen.cpp | 2 +- src/Global.cpp | 25 +++++++-- src/Thread_FileAnalyzer.cpp | 10 +--- src/Thread_Initialization.cpp | 103 +++++++++++++++++++++++++++++----- src/Thread_Initialization.h | 7 ++- 6 files changed, 119 insertions(+), 32 deletions(-) diff --git a/src/Config.h b/src/Config.h index 31d63ff8..a9c6d312 100644 --- a/src/Config.h +++ b/src/Config.h @@ -34,8 +34,8 @@ #define VER_LAMEXP_MINOR_HI 0 #define VER_LAMEXP_MINOR_LO 9 #define VER_LAMEXP_TYPE Alpha -#define VER_LAMEXP_PATCH 6 -#define VER_LAMEXP_BUILD 1444 +#define VER_LAMEXP_PATCH 7 +#define VER_LAMEXP_BUILD 1447 #define VER_LAMEXP_CONFG 1348 /////////////////////////////////////////////////////////////////////////////// diff --git a/src/Dialog_SplashScreen.cpp b/src/Dialog_SplashScreen.cpp index 5b90d85b..c4c65453 100644 --- a/src/Dialog_SplashScreen.cpp +++ b/src/Dialog_SplashScreen.cpp @@ -131,7 +131,7 @@ void SplashScreen::showSplash(QThread *thread) //Start the thread 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())); //Start event handling! diff --git a/src/Global.cpp b/src/Global.cpp index 51cfce37..99415c8a 100644 --- a/src/Global.cpp +++ b/src/Global.cpp @@ -3179,6 +3179,25 @@ void lamexp_fatal_exit(const wchar_t* exitMessage, const wchar_t* errorBoxMessag 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) */ @@ -3189,11 +3208,7 @@ void lamexp_finalization(void) //Free all tools if(g_lamexp_tools.registry) { - QStringList keys = g_lamexp_tools.registry->keys(); - for(int i = 0; i < keys.count(); i++) - { - LAMEXP_DELETE((*g_lamexp_tools.registry)[keys.at(i)]); - } + lamexp_clean_all_tools(); LAMEXP_DELETE(g_lamexp_tools.registry); LAMEXP_DELETE(g_lamexp_tools.versions); LAMEXP_DELETE(g_lamexp_tools.tags); diff --git a/src/Thread_FileAnalyzer.cpp b/src/Thread_FileAnalyzer.cpp index 1da05292..55e627b5 100644 --- a/src/Thread_FileAnalyzer.cpp +++ b/src/Thread_FileAnalyzer.cpp @@ -76,18 +76,12 @@ FileAnalyzer::FileAnalyzer(const QStringList &inputFiles) 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)) { qWarning("There are still running tasks in the thread pool!"); } + LAMEXP_DELETE(m_templateFile); LAMEXP_DELETE(m_pool); LAMEXP_DELETE(m_timer); } @@ -351,7 +345,7 @@ bool FileAnalyzer::createTemplate(void) try { - m_templateFile = new LockedFile(templatePath); + m_templateFile = new LockedFile(templatePath, true); } catch(const std::exception &error) { diff --git a/src/Thread_Initialization.cpp b/src/Thread_Initialization.cpp index bcd18cd8..19e28271 100644 --- a/src/Thread_Initialization.cpp +++ b/src/Thread_Initialization.cpp @@ -45,6 +45,10 @@ /* constants */ static const double g_allowedExtractDelay = 12.0; static const size_t BUFF_SIZE = 512; +static const size_t EXPECTED_TOOL_COUNT = 27; + +/* benchmark */ +#undef ENABLE_BENCHMARK //////////////////////////////////////////////////////////// // ExtractorTask class @@ -188,7 +192,34 @@ InitializationThread::InitializationThread(const lamexp_cpu_t *cpuFeatures) // 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; delay(); @@ -255,11 +286,7 @@ void InitializationThread::run() QDir appDir = QDir(QCoreApplication::applicationDirPath()).canonicalPath(); QThreadPool *pool = new QThreadPool(); - const int idealThreadCount = QThread::idealThreadCount(); - if(idealThreadCount > 0) - { - pool->setMaxThreadCount(idealThreadCount * 2); - } + pool->setMaxThreadCount((threadCount > 0) ? threadCount : qBound(2U, (m_cpuFeatures.count * 2U), EXPECTED_TOOL_COUNT)); LockedFile::selfTest(); ExtractorTask::clearFlags(); @@ -279,7 +306,7 @@ void InitializationThread::run() if(toolHash.size() != 96) { qFatal("The checksum for \"%s\" has an invalid size!", QUTF8(toolName)); - return; + return -1.0; } QResource *resource = new QResource(QString(":/tools/%1").arg(toolName)); @@ -287,7 +314,7 @@ void InitializationThread::run() { LAMEXP_DELETE(resource); qFatal("The resource for \"%s\" could not be found!", QUTF8(toolName)); - return; + return -1.0; } if(cpuType & cpuSupport) @@ -318,10 +345,10 @@ void InitializationThread::run() if(ExtractorTask::getErrMsg(errorMsg, BUFF_SIZE)) { 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!"); - return; + return -1.0; } qDebug("All extracted.\n"); @@ -333,7 +360,7 @@ void InitializationThread::run() } //Check delay - double delayExtract = static_cast(timeExtractEnd - timeExtractStart) / static_cast(lamexp_perfcounter_frequ()); + const double delayExtract = static_cast(timeExtractEnd - timeExtractStart) / static_cast(lamexp_perfcounter_frequ()); if(delayExtract > g_allowedExtractDelay) { m_slowIndicator = true; @@ -353,8 +380,55 @@ void InitializationThread::run() initFhgAac(); initQAac(); - delay(); 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 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 keys = results.keys(); + for(QList::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) { - 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}; LockedFile::selfTest(); @@ -815,7 +888,7 @@ void InitializationThread::selfTest(void) 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]); } @@ -827,4 +900,4 @@ void InitializationThread::selfTest(void) // EVENTS //////////////////////////////////////////////////////////// -/*NONE*/ \ No newline at end of file +/*NONE*/ diff --git a/src/Thread_Initialization.h b/src/Thread_Initialization.h index dca1937c..1ad6e95a 100644 --- a/src/Thread_Initialization.h +++ b/src/Thread_Initialization.h @@ -35,12 +35,17 @@ class InitializationThread: public QThread public: InitializationThread(const lamexp_cpu_t *cpuFeatures); - void run(); + bool getSuccess(void) { return !isRunning() && m_bSuccess; } bool getSlowIndicator(void) { return m_slowIndicator; } static void selfTest(void); +protected: + void run(void); + double doInit(const size_t threadCount = 0); + void runBenchmark(void); + private: void delay(void); void initTranslations(void);