首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PPL和AMP比序贯变换性能差

PPL和AMP比序贯变换性能差
EN

Code Review用户
提问于 2014-07-05 17:10:40
回答 1查看 474关注 0票数 2

我编写了以下简短的测试代码来测试C++AMP和std::transform的顺序STL实现的PPL库的性能。令我惊讶的是,C++AMP和PPL实现都明显不如顺序实现(C++AMP: 128 my,PPL: 51 my,顺序:25 my)。这种模式适用于intfloatdouble数据类型。

对于较小的大小(可能少于几千),我预计顺序代码将是最快的,因为将数据从CPU复制到GPU有很大的时间延迟,而对于PPL来说,线程启动等方面会有轻微的延迟,但是我并不认为大尺寸(100000+)的顺序代码会获胜。

我在Visual 2013中使用以下代码来度量性能,并使用完全优化进行编译:

代码语言:javascript
复制
#include <amp.h>
#include <iostream>
#include <numeric>
#include <random>
#include <assert.h>
#include <functional>
#include <chrono>
const std::size_t size = 30737418;

using namespace concurrency;

//----------------------------------------------------------------------------
// Program entry point.
//----------------------------------------------------------------------------
int main( )
{
    accelerator default_device;
    std::wcout << "Using device : " << default_device.get_description( ) << std::endl;
    if( default_device == accelerator( accelerator::direct3d_ref ) )
        std::cout << "WARNING!! Running on very slow emulator! Only use this accelerator for debugging." << std::endl;

    std::mt19937 engine;
    std::uniform_int_distribution<int> dist( 0, 10000 );

    std::vector<int> vecTest( size );
    std::vector<int> vecTest2( size );
    std::vector<int> vecResult( size );

    for( int i = 0; i < size; ++i )
    {
        vecTest[i] = dist( engine );
        vecTest2[i] = dist( engine );
    }

    std::vector<int> vecCorrectResult( size );

    std::chrono::high_resolution_clock clock;
    auto beginTime = clock.now();

    std::transform( std::begin( vecTest ), std::end( vecTest ), std::begin( vecTest2 ), std::begin( vecCorrectResult ), std::plus<int>() );

    auto endTime = clock.now();
    auto timeTaken = endTime - beginTime;

    std::cout << "The time taken for the sequential function to execute was: " << std::chrono::duration_cast<std::chrono::milliseconds>(timeTaken).count() << "ms" << std::endl;

    beginTime = clock.now();

    concurrency::array_view<const int, 1> av1( vecTest );
    concurrency::array_view<const int, 1> av2( vecTest2 );
    concurrency::array_view<int, 1> avResult( vecResult );
    avResult.discard_data();

    concurrency::parallel_for_each( avResult.extent, [=]( concurrency::index<1> index ) restrict(amp) {
        avResult[index] = av1[index] + av2[index];
    } );

    avResult.synchronize();
    endTime = clock.now();
    timeTaken = endTime - beginTime;

    std::cout << "The time taken for the AMP function to execute was: " << std::chrono::duration_cast<std::chrono::milliseconds>(timeTaken).count() << "ms" << std::endl;
    std::cout << std::boolalpha << "The AMP function generated the correct answer: " << (vecResult == vecCorrectResult) << std::endl;

    beginTime = clock.now();

    concurrency::parallel_transform( std::begin( vecTest ), std::end( vecTest ), std::begin( vecTest2 ), std::begin( vecResult ), std::plus<int>() );

    endTime = clock.now();
    timeTaken = endTime - beginTime;

    std::cout << "The time taken for the PPL function to execute was: " << std::chrono::duration_cast<std::chrono::milliseconds>(timeTaken).count() << "ms" << std::endl;
    std::cout << "The PPL function generated the correct answer: " << (vecResult == vecCorrectResult) << std::endl;

    return 0;
}

我能做些什么来提高并行性能吗?还是简单地说,添加是一种如此快速的操作,以至于并行化的开销总是大于加速比?

EN

回答 1

Code Review用户

回答已采纳

发布于 2014-07-05 19:02:33

在这种情况下,我认为并行执行(至少在CPU之外)不太可能加快速度。问题相当简单:您正在执行的操作(加法)非常简单,内存带宽是整个速度的控制因素。

在CPU上连续执行操作后,您将尽可能快地从内存中读取数据。

对于AMP版本,数据从内存中读取,然后写入GPU的内存,然后GPU读取数据以产生结果,最后将数据写回CPU可以看到的地方。

要了解AMP在哪里可以提供优势,您几乎肯定需要对数据执行更多的操作,因此总体时间要远远大于从内存中获取原始数据的时间。

票数 2
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/56211

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档