/** \example multithreaded.cpp * Using JKQTBasePlotter in multiple threads in parallel. * * \ref JKQTPlotterMultiThreaded */ #include #include #include #include #include #include #include #include #include "multithreaded_thread.h" #include "jkqtmath/jkqtpstatbasics.h" #include "jkqtpexampleapplication.h" #include "jkqtplotter_version.h" #define NUM_SHOWN_PLOTS 3 #define NUM_PLOTS 8 #define NUM_GRAPHS 6 #define NUM_DATAPOINTS 1000 #define NUM_REPEATS 3 int main(int argc, char* argv[]) { JKQTPAppSettingController highDPIController(argc,argv); JKQTPExampleApplication app(argc, argv); QMainWindow* mainWin=new QMainWindow(); mainWin->setWindowTitle("Multi-Threaded Plotting"); QWidget* main; mainWin->setCentralWidget(main=new QWidget(mainWin)); QString markdownFile=""; QString labelTemplate="Plot %1: $f(x)=\\cos\\left(x+\\sfrac{%1\\pi}{8}\\right)$"; QByteArray mdMATCH="RESULTS"; for (int i=1; isetLayout(mainLayout); QVBoxLayout* lay_serial=new QVBoxLayout(); QVBoxLayout* lay_parallel=new QVBoxLayout(); mainLayout->addLayout(lay_serial); QLabel* l; lay_serial->addWidget(l=new QLabel("Serialized Plotting")); QFont f=l->font(); f.setBold(true); f.setPointSize(16); l->setFont(f); lay_parallel->addWidget(l=new QLabel("Parallel Plotting")); l->setFont(f); QLabel* labSerialResult=new QLabel(main); lay_serial->addWidget(labSerialResult); QLabel* labParallelResult=new QLabel(main); lay_parallel->addWidget(labParallelResult); mainLayout->addLayout(lay_parallel); QVector pic_parallel, pic_serial; for (int i=0; iaddWidget(pic_serial.last(), 1); lay_parallel->addWidget(pic_parallel.last(), 1); } QList runtimesParallel; QList runtimesSerial; double durSerialNano=0; double durParallelNano=0; for (int run=0; run> threads; for (int i=0; i::create("parallel",i, NUM_GRAPHS, NUM_DATAPOINTS, labelTemplate, nullptr)); } timer.start(); for (int i=0; istart(); } for (int i=0; iwait()) { filenamesParallel<getFilename(); runtimesParallel<getRuntimeNanosends()/1e6; } } durParallelNano+=timer.nsecsElapsed(); qDebug()<<"durParallel["<NUM_SHOWN_PLOTS/2) i=NUM_PLOTS-1-NUM_SHOWN_PLOTS+ii; pic_serial[ii]->setPixmap(QPixmap(filenamesSerial[i], "PNG")); pic_parallel[ii]->setPixmap(QPixmap(filenamesParallel[i], "PNG")); } QString ser_result, par_result; labSerialResult->setText(ser_result=QString("runtime, overall = %1ms
single runtimes = (%2 +/- %3) ms
speedup = %4x
threads / available = %5 / %6


").arg(durSerialNano/1e6,0,'f',1).arg(jkqtpstatAverage(runtimesSerial.begin(), runtimesSerial.end()),0,'f',1).arg(jkqtpstatStdDev(runtimesSerial.begin(), runtimesSerial.end()),0,'f',1).arg(jkqtpstatSum(runtimesSerial.begin(), runtimesSerial.end())/(durSerialNano/1e6),0,'f',2).arg(1).arg(std::thread::hardware_concurrency())); labParallelResult->setText(par_result=QString("runtime, overall = %1ms
single runtimes = (%2 +/- %3) ms
speedup = %4x
threads / available = %5 / %6
batch runs = %8

speedup vs. serial = %7x").arg(durParallelNano/1e6,0,'f',1).arg(jkqtpstatAverage(runtimesParallel.begin(), runtimesParallel.end()),0,'f',1).arg(jkqtpstatStdDev(runtimesParallel.begin(), runtimesParallel.end()),0,'f',1).arg(jkqtpstatSum(runtimesParallel.begin(), runtimesParallel.end())/(durParallelNano/1e6),0,'f',2).arg(NUM_PLOTS).arg(std::thread::hardware_concurrency()).arg(durSerialNano/durParallelNano,0,'f',1).arg(NUM_REPEATS)); mainWin->show(); if (!markdownFile.isEmpty()) { qDebug()<<"modifying MD-file "<VERSION: "+QByteArray(JKQTPLOTTER_VERSION::PROJECT_VERSION) +"\nBUILD MODE: "+QByteArray(JKQTPLOTTER_VERSION::PROJECT_BUILDTYPE) +"\n\nSERIAL RESULTS:
"+ser_result.toUtf8() +"\n\nPARALLEL RESULTS:
\n"+par_result.toUtf8()+"\n\n"; md.replace(istart,iend-istart,newResults); if (f.open(QFile::WriteOnly)) { qDebug()<<" writing "<