Your SlideShare is downloading. ×
0
Qt Concurrent
Qt Concurrent
Qt Concurrent
Qt Concurrent
Qt Concurrent
Qt Concurrent
Qt Concurrent
Qt Concurrent
Qt Concurrent
Qt Concurrent
Qt Concurrent
Qt Concurrent
Qt Concurrent
Qt Concurrent
Qt Concurrent
Qt Concurrent
Qt Concurrent
Qt Concurrent
Qt Concurrent
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Qt Concurrent

568

Published on

Utilizza al meglio i core della tua macchina

Utilizza al meglio i core della tua macchina

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
568
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
16
Comments
0
Likes
0
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. QtConcurrent David Mugnaidvd@develer.com
  • 2. QtConcurrent #include <QtCore>using namespace QtConcurrent since Qt 4.4
  • 3. Che cosè QtConcurrentAPI di alto livello per multi tasking shared memory niente lock, semafori, mutex pensata per task cpu boundThreadPool con dimensione uguale al numero di coreun API comoda da usare quasi zero boilerplate in puro stile Qt!
  • 4. Che cosa cè in QtConcurrentMapReduce e FilterReduceQtConcurrent::run per accodare task asincroniQFuture per conoscere lo stato di avanzamento dellelaborazione
  • 5. Map|Filter + Reduce Costrutti nati nellambito della programmazione funzionalea2 = map(f, a1) a2 = filter(f, a1) result = reduce(f, a) a2[0] = f(a1[0]) foreach(e in a1) { result = f(a[0], a[1]) a2[1] = f(a1[1]) if(f(e)) result = f(result, a[2]) a2[2] = f(a1[2]) a2 << e result = f(result, a[3]) ... } ... a2[n] = f(a1[n]) result = f(result, a[n])portati alla ribalta nel 2004 da Google con il framework MapReducesi prestano naturalmente alla parallelizzazione se si rispettalinvariante che f non abbia stato condiviso.
  • 6. DATASET Map|Filter + Reduce REDUCE Map parallelo Reduce sequenziale un thread per core ordered o unordered (automatico) MAP
  • 7. MapReduce#include <QVector>#include <QtCore>#include <iostream>#include <math.h> const reference (no copy)struct Triangle { float ax, ay; float bx, by; float cx, cy;};float area(const Triangle& t) { return 0.5 * fabs(t.ax*t.by - t.ax*t.cy + t.bx*t.cy - t.bx*t.ay +t.cx*t.ay - t.cx*t.by);}void sum(float& a, const float& b) { a += b; }int main() { il risultato della reduce nel primo argomento QVector<Triangle> triangles(100000); // fill triangles QFuture<float> f = QtConcurrent::mappedReduced(triangles, area, sum); std::cout << f.result() << std::endl;} bloccante, ritorna quando tutti I task sono completati
  • 8. Map in placestruct Point { float real, img; ; int iteration; ;}};void mandelbrot(Point& p) { float x = 0, y = 0;; p.iteration = 0; ; while(x*x + y*y < 4 && p.iteration < 1000) { float t = x*x - y*y + p.real; ; y = 2*x*y + p.img; ; x = t; ; p.iteration++; + }}int main() { QVector<Point> points(100000); ) QtConcurrent::map(points, mandelbrot).waitForFinished(); (}
  • 9. QFutureè un collegamento tra il programma che ha avviato il task e il task stesso permette di mettere in pausa, riprendere o annullare il task ma non per QtConcurrent::runè il meccanismo per sapere se il task è completato e per recuperarne il risultatoè lunico meccanismo di sincronizzazione in QtConcurrent
  • 10. QFutureNon è un QObjectÈ thread-safe ad eccezione di ::const_iteratorreference counted pass by value
  • 11. QFutureUn QFuture può dare accesso a più di un risultato: QFuture<float> f = QtConcurrent::map(seq, f).resultAt(int) // .results() // .results()Tutti ritornano immediatamente se il risultato è disponibile altrimenti bloccano.resultCount() → risultati sono disponibili
  • 12. QFuture introspezione.isRunning() solo per map|filter.isFinished() .cancel() .pause() .resume() .progress*()
  • 13. QFutureWatcherpermette di “monitorare” un QFuture .setFuture(QFuture)è un QObject emette segnali per comunicare lo stato del QFuture utilizza gli slot per controllarloper comodità ripropone quasi tutta lapi del QFuture
  • 14. QFutureWatcher recipeistanziare QFutureWatcher()connettere connect(&w, SIGNAL(finished()), &o, SLOT(end()));chiamare .setWatcher w.setWatcher(f)
  • 15. QtConcurrent::runaccoda un task nel thread pool di QtConcurrentpermette di implementare una coda di task con “zero effort” senza sbattimento :)
  • 16. QtConcurrent::run + QFutureWatchervoid Viewer::addImage(QString fname) { QFutureWatcher<QImage>* watcher = new QFutureWatcher<QImage>(this); ; mapper->setMapping(watcher, watcher); ; connect(watcher, SIGNAL(finished()), mapper, SLOT(map())); ; QFuture<QImage> f = QtConcurrent::run(this, &Viewer::openImage, fname); ; watcher->setFuture(f); ;}void Viewer::taskComplete(QObject* s) { QFutureWatcher<QImage>* w = (QFutureWatcher<QImage>*)s; ; emit previewReady(w->result()); ; w->deleteLater(); ;}QImage Viewer::openImage(QString& fname) { return QImage(fname).scaled(64, 64, Qt::KeepAspectRatio); ;}
  • 17. Un API comoda da usaremap/reduce accettano container STL container Qt iteratori int filter(int x) { … } std::vector<int> v1(); QtConcurrent::mapped(v1, filter);
  • 18. Un API comoda da usare::run() supporta funzioni con/senza parametri metodi di istanza std::tr1::bind (C++11) MyObject o; // reference for const method QtConcurrent::run(o, &MyObject::compute, 1000) // pointer for non const method QtConcurrent::run(&o, &MyObject::update, 2000)
  • 19. QtConcurrentdvd@develer.com

×