使用嵌套的zip_iterator时,odeint推力会大幅减慢

时间:2014-10-27 15:45:23

标签: thrust odeint

我正在odeint和推力之上构建一个分析工具。该工具解决了大量初始条件问题。我在odeint和推力教程/演示之后取得了成功。到目前为止,我一直在使用的系统有少于5个状态变量,但现在我需要扩展系统以便能够处理更多。

正如教程中所提到的,推文的元组最多只能包含10个项目。使用嵌套的zip_iterators可以解决此问题。

one of the tutorials底部附近引用:

  

“Thrust的元组最小为10的小难度。但这只是一个小问题,因为我们可以创建一个包含zip迭代器的zip迭代器。所以顶级zip迭代器包含一个用于状态的zip迭代器,参数的一个普通迭代器,以及派生的一个zip迭代器。“

我已经实施了这个解决方案,但它很有效,但遗憾的是速度大幅下降。对于同一系统(双变量系统,同时求解8192初始条件),原始的,简单但不可扩展的超过5个变量解决方案在一秒钟内运行:

real   0m1.244s
user   0m0.798s
sys    0m0.356s

而更复杂但可扩展的嵌套解决方案需要大约2000倍的时间!

real    4m3.613s
user    2m15.124s
sys     1m47.363s

两个程序之间的唯一区别是

  1. 在仿函数operator()中,我指的是状态变量和派生词,

  2. 在仿函数的构造函数中,特别是for_each命令,我在其中创建了zip_iterators和元组。

  3. 下面我列出了每个节目的摘录。我希望我在这里做错了,因为这种速度损失是毁灭性的!任何帮助将不胜感激。

    “SIMPLE”代码(非嵌套迭代器)

    的摘录
    //////////////////////////////////////////////////////////
    //// Inside ICFunctor's operator()
    // getting the state variable
    value_type X = thrust::get< 0 >( t );
    
    // setting the derivative
    thrust::get< 2 >( t ) = 0.5*A - 1.5*X;
    
    //////////////////////////////////////////////////////////
    //// the for_each statement that creates the zip_iterator
    thrust::for_each(
        //// START INDICES
        thrust::make_zip_iterator( thrust::make_tuple(
            // State-variables
            boost::begin( x ) + 0*m_N,
            boost::begin( x ) + 1*m_N,
            // Derivatives
            boost::begin( dxdt ) + 0*m_N,
            boost::begin( dxdt ) + 1*m_N)) ,
        //// END INDICES
        thrust::make_zip_iterator( thrust::make_tuple(
            // State-variables
            boost::begin( x ) + 1*m_N,
            boost::begin( x ) + 2*m_N,
            // Derivatives
            boost::begin( dxdt ) + 1*m_N,
            boost::begin( dxdt ) + 2*m_N)) ,
    ICFunctor() );
    

    “可扩展”代码(嵌套迭代器)

    的摘录
    //////////////////////////////////////////////////////////
    //// Inside ICFunctor's operator()
    // getting the state variable
    const int STATE_VARIABLES = 0; // defined as a global constant 
    value_type X = thrust::get<0>(thrust::get<STATE_VARIABLES>( t ));
    
    // setting the derivative
    const int DERIVATIVES = 1; // defined as a global constant 
    thrust::get<0>(thrust::get<DERIVATIVES>( t )) = 0.5*A - 1.5*X;
    
    //////////////////////////////////////////////////////////
    //// the for_each statement that creates the zip_iterator
    thrust::for_each(
        //// START INDICES
        thrust::make_zip_iterator( thrust::make_tuple(
            // State variables
            thrust::make_zip_iterator( thrust::make_tuple(
                boost::begin( x ) + 0*m_N,
                boost::begin( x ) + 1*m_N)),
            // Derivatives
            thrust::make_zip_iterator( thrust::make_tuple(
                boost::begin( dxdt ) + 0*m_N,
                boost::begin( dxdt ) + 1*m_N))
        )), 
        //// END INDICES
        thrust::make_zip_iterator( thrust::make_tuple(
            // State variables
            thrust::make_zip_iterator( thrust::make_tuple(
                boost::begin( x ) + 1*m_N,
                boost::begin( x ) + 2*m_N)),
            // Derivatives
            thrust::make_zip_iterator( thrust::make_tuple(
                boost::begin( dxdt ) + 1*m_N,
                boost::begin( dxdt ) + 2*m_N))
        )),
        ICFunctor() );
    

0 个答案:

没有答案