Quantcast
Channel: Active questions tagged gcc - Stack Overflow
Viewing all articles
Browse latest Browse all 21994

Qt: QtConcurrent - Why does the pointer not change?

$
0
0

I'm doing my first steps in QtConcurrent. I try to implement an iterating calculation and in order to avoid copying large amount of data (in this example it's reduced for demonstration purpose) I implement something similar like a double buffer in a shared data object (derived from QSharedData) and accessed via QSharedDataPointer.

qtconcurrent_example.h

#ifndef QTCONCURRENT_EXAMPLE_H_INCLUDED
#define QTCONCURRENT_EXAMPLE_H_INCLUDED

#include <functional>
#include <QList>
#include <QDebug>
#include <QSharedData>

typedef QVector<double> StateType;

class StateData : public QSharedData
{
    StateType state_left;
    StateType state_right;
public:
    StateType* state_cur;
    StateType* state_new;

public:
    StateData(StateType initState){
        this->state_left = initState;
        this->state_right = StateType();
        this->state_right.resize(initState.length());
        this->state_cur = &(this->state_left);
        this->state_new = &(this->state_right);
    }
    void swap(){
        qInfo() << "## swap start ##"<< " cur:"<< QString::pointer(this->state_cur)
                << " new:"<< QString::pointer(this->state_new);
        StateType* cur = this->state_cur;
        this->state_cur = this->state_new;
        this->state_new = cur;
        qInfo() << "## swap end   ##"<< " cur:"<< QString::pointer(this->state_cur)
                << " new:"<< QString::pointer(this->state_new);
    }
};

typedef QSharedDataPointer<StateData> State;
typedef std::function<double(const StateType&)> Odefun;

class WorkItem
{
public:
    WorkItem(int index, State data, Odefun odefun){
        this->index = index;
        this->data = data;
        this->odefun = odefun;
    }
    int index;
    State data;
    Odefun odefun;
};


class QtConcurrent_example
{
    // shared data pointer to the state data
    State state;

public:
    QtConcurrent_example();
};

#endif // QTCONCURRENT_EXAMPLE_H_INCLUDED

qtconcurrent_example.cpp

#include "qtconcurrent_example.h"

#include <QtConcurrent>

QtConcurrent_example::QtConcurrent_example()
{
    // initialize state data and link the objet to the shared
    // data pointer
    StateType init = {1,2,3};
    state = new StateData(init);

    qInfo() << "\t"<< QString::number(state.data()->state_cur->at(0))
            << "\t"<< QString::number(state.data()->state_cur->at(1))
            << "\t"<< QString::number(state.data()->state_cur->at(2))
            << "\tp:"<< QString::pointer(state.data()->state_cur);

    QList<WorkItem> workSet;
    workSet.append( WorkItem( 0, state,
                          [](const StateType &s){
                              return s.at(0)*2;
                          } ));

    workSet.append( WorkItem( 1, state,
                          [](const StateType &s){
                              return s.at(1)*2;
                          } ));

    workSet.append( WorkItem( 2, state,
                          [](const StateType &s){
                              return s.at(2)*2;
                          } ));

    std::function<void(const WorkItem &)> step =
          [](const WorkItem &wi){
              qInfo() << "## step       ##"<< " cur:"<< QString::pointer(wi.data.data()->state_cur)
                        << " new:"<< QString::pointer(wi.data.data()->state_new);
                // apply ode at index
                auto r = wi.odefun(*wi.data.data()->state_cur);
                // apply integration
                r = wi.data.data()->state_cur->at(wi.index) + r*0.01;
                // store data
                wi.data.data()->state_new->replace(wi.index, r);
          };

    StateType* cur;
    for(int i=0; i<10; i++){

        cur = state.data()->state_cur;
        qInfo() << "apply blockingMap step"<< "\tp:"<< QString::pointer(cur);
        QtConcurrent::blockingMap(workSet, step);

        cur = state.data()->state_cur;
        qInfo() << "apply swap"<< "\tp:"<< QString::pointer(cur);
        state.data()->swap();

        cur = state.data()->state_cur;
        qInfo() << "> i="<< QString::number(i)
                << "\t"<< QString::number(cur->at(0))
                << "\t"<< QString::number(cur->at(1))
                << "\t"<< QString::number(cur->at(2))
                << "\tp:"<< QString::pointer(cur);
    }


}

The corresponding output is:

"1""2""3"    p: 0x55c3f5d06a08
## swap start ##  cur: 0x55c3f5d06a08  new: 0x55c3f5d06a10
## swap end   ##  cur: 0x55c3f5d06a10  new: 0x55c3f5d06a08
apply blockingMap step  p: 0x55c3f5d06a10
## step       ##  cur: 0x55c3f5d06a08  new: 0x55c3f5d06a10
## step       ##  cur: 0x55c3f5d06a10  new: 0x55c3f5d06a08
## step       ##  cur: 0x55c3f5d06a10  new: 0x55c3f5d06a08
apply swap  p: 0x55c3f5d06a10
## swap start ##  cur: 0x55c3f5d06a10  new: 0x55c3f5d06a08
## swap end   ##  cur: 0x55c3f5d06a08  new: 0x55c3f5d06a10
  > i= "0""1""0""0"    p: 0x55c3f5d06a08
apply blockingMap step  p: 0x55c3f5d06a08
## step       ##  cur: 0x55c3f5d06a08  new: 0x55c3f5d06a10
## step       ##  cur: 0x55c3f5d06a10  new: 0x55c3f5d06a08
## step       ##  cur: 0x55c3f5d06a10  new: 0x55c3f5d06a08
apply swap  p: 0x55c3f5d06a08
## swap start ##  cur: 0x55c3f5d06a08  new: 0x55c3f5d06a10
## swap end   ##  cur: 0x55c3f5d06a10  new: 0x55c3f5d06a08
  > i= "1""1.02""0""0"    p: 0x55c3f5d06a10
apply blockingMap step  p: 0x55c3f5d06a10
## step       ##  cur: 0x55c3f5d06a08  new: 0x55c3f5d06a10
## step       ##  cur: 0x55c3f5d06a10  new: 0x55c3f5d06a08
...

And I do not get it, why the pointer state_cur is always the same inside QtConcurrent::blockingMap(workSet, step) even if it change outside (due to swap).

Why?


It looks to me as the pointer will fixed while

    workSet.append( WorkItem( 0, state,
                          [](const StateType &s){
                              return s.at(0)*2;
                          } ));

Because: if I call

state.data()->swap();

bevore, between or behind the three workSet.append(...) calls, it does effect the pointer inside the corresponding call, although the pointer state_cur does not change anymore.


Removing the const's does not help - as expected.


Viewing all articles
Browse latest Browse all 21994

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>