PDA

View Full Version : QtConcurent and QCache



baray98
11th May 2010, 07:59
My aim is to make my calculation as fast as possible. I have an object that will calculate and store results in an array and hold those values until its life - meaning the object will just the do the long calculation for the first time then throughout its life it will just fetch from its array of values. fetching from its array is much faster than calculating it again. Each object is responsible for a record in my millions of records.

I used QtConcurrent to do my "get all objects that i need " and ask each object for its values (which will give me an array). This will maximize my computational power using threads. This is all working but then all the object in each iteration on each thread is created and deleted. There are times that some iterations can operate on the same object the i could have save some calculation cost if i did not delete the object. This leads me to caching.

The problem with caching is that the object that i cache is created from other thread so techinically i am breaking the laws of threading

Have you have any scenarion like this and came up with an elegant solution?




MyObject* DataSource::getObject(int index)
{
//check if its in cache
MyObject* o = isInCache(index);
if (o) return o;
//if not
o = new MyObject();
addToCache(index,o); //note : o will be created under whoever thread is calling so the next time i will give to other thread this will error out
return o;
}
struct MyInfo
{
int index;
DataSource* source;
}
void process(MyInfo info)
{
MyObject* obj = info.source->getObject(info.id)
QVector < double> values = obj->getMeValues();
....
}

MyClass::fillValues()
{
//somewhere i got my datasource instantiated
//get all index
QVector<info> index = getAllIndexThatIneed();
QFutureWatcher<void> fw = setFuture(QtConcurrent::map(index, process));
//wait till finished
}

wysota
11th May 2010, 09:51
You can wrap your cache in a class that will provide appropriate synchronization using i.e. QReadWriteLock. It will slow down processing a bit but you won't wreck your cache.

baray98
11th May 2010, 18:54
I actually have a locker at my getObject but it did not help. My problem is that when i created MyObject it will be attached to the current thread, and some other thread was given by it when its available on my cache. I don't think there is racing issue, i think its just the limitation of having a cache.

I have another problem to deal with when cache deletes the objects to make room and maybe the object is used by other thread. i think i will deal with this later .. or should i .. or maybe they are of the same nature..

thanks for the inpit wysota.. keep it coming.

baray98



MyObject* DataSource::getObject(int index)
{
QMutexLocker (&mutex) ; //<--this exist but it did not help
//check if its in cache
MyObject* o = isInCache(index);
if (o) return o;
//if not
o = new MyObject();
addToCache(index,o); //note : o will be created under whoever thread is calling so the next time i will give to other thread this will error out
return o;
}

wysota
11th May 2010, 21:54
Does MyObject inherit QObject?

baray98
13th May 2010, 05:04
yes .. is it bad?

baray98

wysota
13th May 2010, 08:46
Yes, it is. QObjects are not thread-safe, you can't use them from within different threads at once.

baray98
14th May 2010, 07:45
So if i pull this MyObject out of QObject should solve my threading problem .. interesting .. i should try it.

baray98