728x90
반응형
MapReducde는 구글이 제안한 분산 처리를 위한 개발 모델입니다. 조엘은 소프트웨어를 넘어서 에서도 소개되기도 한 이 방법은 대용량 자료의 분산 처리에 유용한 구조입니다.
이미 하둡 등의 프레임워크가 많이 나와 있으며, 미래의 컴퓨터 언어는 이런 처리를 기본 사양으로 제공해 줄 가능성이 높습니다. 물론 기존의 컴퓨터 언어도 미래형 언어로 변신하려면 이런 기능을 끌어 안아야 할 것입니다.
그런데 Qt 쪽에도 이런 기능이 있는가 하는 것을 찾아 보다 보니 QtConcurrent 가 있습니다. 주 대상은 멀티코어 프로그램 개발이 필요한 경우에 저수준 인터페이스의 지원을 넘어서, 고수준의 인터페이스 제공을 목적으로 하고 있습니다.
하지만, 향후 함수형 언어의 사용을 지향하는 MapReduce 모델과 객체지향 기반 모델인 Qt를 융합하는 방향이 어떻게 될 지는 노키아(201x)의 향후 방향을 계속 지켜봐야 할 것입니다. [본문 초안은 2011년에 작성되었습니다.]
아래는 필자가 작성한 예제이며, 듀얼코어 CPU라면 한번에 두 개까지만의 쓰레드가 실행됨을 확인할 수 있을 것입니다. 물론 두 개의 쓰레드는 듀얼코어에서 사용하기 가장 이상적인 쓰레드 개수입니다.
예제 실행을 원하면 Nokia Qt 사이트에서 LGPL 지원하는 Qt SDK 를 받아서, 콘솔 예제를 실행해 보면 됩니다.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <climits> | |
#include <QtGlobal> | |
#include <QString> | |
#include <QDebug> | |
#include <QtCore> | |
#include <QtCore/QCoreApplication> | |
#include <QThread> | |
#include <QtConcurrentRun> | |
#include <QTime> | |
#include <QDateTime> | |
#ifndef QT_NO_CONCURRENT | |
using namespace QtConcurrent; | |
void timeConsumingFunction(QString name) | |
{ | |
qDebug() << QThread::currentThread() | |
<< "(" << __FUNCTION__ << ")" | |
<< "[START]\t" << "NAME : " << name; | |
QTime spanTime; | |
spanTime.start(); | |
double cardSoldier = 0; | |
for ( int heart = 1 ; heart < 20000 ; heart ++ ) | |
{ | |
for ( int spade = 1 ; spade < 20000 ; spade ++ ) | |
{ | |
cardSoldier = cardSoldier + ( double(heart) / double(spade) ); | |
} | |
} | |
quint32 milliSecond = spanTime.elapsed(); | |
qDebug() << QThread::currentThread() | |
<< "(" << __FUNCTION__ << ")" | |
<< "[END]\t" << "NAME : " << name | |
<< ", elapsed time = " << milliSecond ; | |
} | |
int main(int argc, char **argv) | |
{ | |
QCoreApplication app(argc, argv); | |
// the amount of cores on your pc | |
qDebug() << " IDLE THREAD COUNT : " << QThread::idealThreadCount (); | |
QFuture<void> helloAlice = run( timeConsumingFunction, QString("Alice") ); | |
QFuture<void> helloWhiteRabbit = run( timeConsumingFunction, QString("White Rabbit") ); | |
QFuture<void> helloMadHatter = run( timeConsumingFunction, QString("Mad Hatter") ); | |
QFuture<void> helloRedQueen = run( timeConsumingFunction, QString("Red Queen") ); | |
QFuture<void> helloHumptyDumpty = run( timeConsumingFunction, QString("Humpty Dumpty") ); | |
QTime spanTime; | |
spanTime.start(); | |
helloAlice.waitForFinished(); | |
helloWhiteRabbit.waitForFinished(); | |
helloMadHatter.waitForFinished(); | |
helloRedQueen.waitForFinished(); | |
helloHumptyDumpty.waitForFinished(); | |
quint32 milliSecond = spanTime.elapsed(); | |
qDebug() << QThread::currentThread() | |
<< "(" << __FUNCTION__ << ")" | |
<< " elapsed time = "<< milliSecond ; | |
return app.exec(); | |
} | |
#else | |
int main(int argc, char **argv) | |
{ | |
QCoreApplication app(argc, argv); | |
qDebug() << "Qt Concurrent is not yet supported on this platform"; | |
return 0; | |
} | |
#endif | |
// | |
// *** Concurrent Programming for Qt *** | |
// | |
// The QtConcurrent namespace provides high-level APIs that make it possible | |
// to write multi-threaded programs without using low-level threading primitives | |
// such as mutexes, read-write locks, wait conditions, or semaphores. | |
// Programs written with QtConcurrent automatically adjust the number of threads | |
// used according to the number of processor cores available. This means that | |
// applications written today will continue to scale when deployed on | |
// multi-core systems in the future. | |
// | |
// QtConcurrent includes functional programming style APIs for parallel list p | |
// rocessing, including a MapReduce and FilterReduce implementation for | |
// shared-memory (non-distributed) systems, and classes for managing | |
// asynchronous computations in GUI applications: | |
// | |
// * QtConcurrent::map() applies a function to every item in a container, | |
// modifying the items in-place. | |
// * QtConcurrent::mapped() is like map(), except that it returns a new | |
// container with the modifications. | |
// * QtConcurrent::mappedReduced() is like mapped(), except that the modified | |
// results are reduced or folded into a single result. | |
// * QtConcurrent::filter() removes all items from a container based on the | |
// result of a filter function. | |
// * QtConcurrent::filtered() is like filter(), except that it returns a new | |
// container with the filtered results. | |
// * QtConcurrent::filteredReduced() is like filtered(), except that the | |
// filtered results are reduced or folded into a single result. | |
// * QtConcurrent::run() runs a function in another thread. | |
// * QFuture represents the result of an asynchronous computation. | |
// * QFutureIterator allows iterating through results available via QFuture. | |
// * QFutureWatcher allows monitoring a QFuture using signals-and-slots. | |
// * QFutureSynchronizer is a convenience class that automatically synchronizes | |
// several QFutures. | |
// | |
728x90
반응형
'C C++' 카테고리의 다른 글
get glibc version (0) | 2011.07.16 |
---|---|
리눅스 환경에서 tzset()와 fork() 간의 잠금 문제 분석 및 해결 방안 (0) | 2011.07.12 |
const object 상수형 객체 (0) | 2010.09.09 |
c++ std exception example (0) | 2010.05.04 |
[CodeBlocks & wxPack] 손쉽게 Windows에서 wxWidgets(wxWindows) 개발 환경 구성하기 (3) | 2009.10.30 |