I am creating a vector class which can be manipulated on the GPU and I am using C++AMP for the GPU accelerated code.
I am wondering the most efficient way of assigning elements of a different type to a concurrency::array
in C++AMP. There are two ways that I can think of (but there may be more):
Firstly, one could use a simple sequential for
loop and use the concurrency::array_view
object to assign the data members and then call concurrency::array_view::synchronize
at the end to ensure the data is stored on the accelerator for subsequent operations, this would look like following:
template <typename T>
CVector& operator=( T tArray[Size] )
{
static_assert( std::is_convertible<T, NumType>::value, "Cannot assign a vector from an array of non-convertible type" );
concurrency::array_view<NumType, 1> avThis( m_numArray.view_as( m_numArray.extent ) );
for( std::size_t s = 0; s < Size; ++s )
{
avThis(s) = static_cast<NumType>(tArray[s]);
}
avThis.synchronize();
return *this;
}
Alternatively, one could construct a concurrency::array_view
from the array and then use a concurrency::parallel_for_each
to assign the data members as follows:
template <typename T>
CVector& operator=( T tArray[Size] )
{
static_assert( std::is_convertible<T, NumType>::value, "Cannot assign a vector from an array of non-convertible type" );
concurrency::array_view<const T, 1> avArray( Size, tArray );
concurrency::parallel_for_each( m_numArray.extent, [=, &m_numArray]( concurrency::index<1> index ) restrict(amp) {
m_numArray[index] = static_cast<NumType>(avArray[index]);
} );
return *this;
}
Which of these methods results in better performance or are they equal?
I profiled the code, and using the Microsoft Concurrency Visualizer, produced the following graph: