花了这么长时间?

时间:2014-03-23 22:07:38

标签: c++ templates

我正在玩一个用于通用工业自动化的lib。为此,我需要一个通用的IO类。

IO.h

template<class T> class IOImpl {}; // pimpl idiom
template<class T> class Input;

/** IO Class
 * A thread safe variable that can be reduced to a read only object
 */
template<class T>
class IO : public AbstractHMIVar
{
public:
    IO( std::string name = "" );
    IO( const IO<T> &io );
    const T value() const;
    void setValue( const T value );
    Input<T> toInput() const;
    IO<T> operator-=( const T &other );
    IO<T> operator+=( const T &other );
    IO<T> operator--();
    IO<T> operator++();
    const std::string stringval() const;
    void fromString( const std::string val );


private:
    std::shared_ptr<IOImpl<T>> pimpl_;
    std::shared_ptr<std::pair<T, std::mutex>> data;
};

IO.cpp

/** Default constructor
 * Create data object
 */
template<class T>
IO<T>::IO( std::string name ) : AbstractHMIVar( name ),
                                pimpl_( std::make_shared<IOImpl<T>>() ),
                                data( std::make_shared<std::pair<T, std::mutex>>() )
{
}

/** Copy constructor
 * Don't allow deep copies. Only copy the shared pointer.
 */
template<class T>
IO<T>::IO( const IO<T> &io ) : pimpl_( io.pimpl_ ), data( io.data )
{
}

/** Return the value part of data pair
 */
template<class T>
const T IO<T>::value() const
{
    std::lock_guard<std::mutex> lock{ data->second };

    return data->first;
}

/** Return a read only version of this object
 */
template<class T>
Input<T> IO<T>::toInput() const
{
    return Input<T>( *this );
}

template<class T>
IO<T> IO<T>::operator--()
{ 
    static_assert( std::is_arithmetic<T>::value, "Type needs to be arithmetic." );

    std::lock_guard<std::mutex> lock{ data->second };
    data->first -= 1;

    return *this;
}

template class IO<int32_t>;

问题

我编写了一个小程序来测试这个IO类的性能。

for( auto i = 0; i < n_tests; i++ )
{
    IO<uint32_t> io_test( "Testvar" ); //unsigned int test
    io_test.setValue( n_iterations );  //test = n_iterations
    high_resolution_clock::time_point before = high_resolution_clock::now();
    while( io_test.value() > 0 ) //while( test > 0 )
        --io_test;               //--test

    results.push_back( duration_cast<milliseconds>( high_resolution_clock::now() - before ) );
}

运行80 000 000次迭代需要11.7秒。 使用不带IO类的普通uint32_t在0.0662秒内运行相同的代码。

我试图跳过共享指针,只使用没有共享指针和互斥锁定的值。但这花了很长时间。

我在编译时也尝试了不同的优化级别。没有区别。

为什么要花这么长时间?

修改

我尝试更改以下内容:

template<class T>
IO<T> IO<T>::operator--()
{ 
    testvar -= 1;
    return *this;
}

template<class T>
const T IO<T>::value() const
{
    return testvar;
}

1 个答案:

答案 0 :(得分:1)

问题在于我的操作员返回了一个IO,每次迭代都会调用复制构造函数。解决方案是:

T IO<T>::operator--();

这更像是我想要的行为。

非常感谢Paul R将我推向了剖析工具。 (之前没用过)