我是AMP C ++中的非常新手。如果我在'parallel_for_each'函数中使用'memcpy',一切正常,但我知道这不是最好的做法。我尝试使用'copy_to',但它引发了异常。下面是一个简化的代码,重点是问题,我遇到了麻烦。提前谢谢。
typedef std::vector<DWORD> CArrDwData;
class CdataMatrix
{
public:
CdataMatrix(int nChCount) : m_ChCount(nChCount)
{
}
void SetSize(UINT uSize)
{
// MUST be multiple of m_ChCount*DWORD
ASSERT(uSize%sizeof(DWORD) == 0);
m_PackedLength = uSize/sizeof(DWORD);
m_arrChannels.resize(m_ChCount*m_PackedLength);
}
UINT GetChannelPackedLen() const
{
return m_PackedLength;
}
const LPBYTE GetChannelBuffer(UINT uChannel) const
{
CArrDwData::const_pointer cPtr = m_arrChannels.data() + m_PackedLength*uChannel;
return (const LPBYTE)cPtr;
}
public:
CArrDwData m_arrChannels;
protected:
UINT m_ChCount;
UINT m_PackedLength;
};
void CtypDiskHeader::ParalelProcess()
{
const int nJobs = 6;
const int nChannelCount = 3;
UINT uAmount = 250000;
int vch;
CArrDwData arrCompData;
// Check buffers sizes
ASSERT((~uAmount & 0x00000003) == 3); // DWORD aligned
const UINT uInDWSize = uAmount/sizeof(DWORD); // in size give in DWORDs
CdataMatrix arrChData(nJobs);
arrCompData.resize(nJobs*uInDWSize);
vector<int> a(nJobs);
for(vch = 0; vch < nJobs; vch++)
a[vch] = vch;
arrChData.SetSize(uAmount+16); // note: 16 bytes or 4 DWORDs larger than uInDWSize
accelerator_view acc_view = accelerator().default_view;
Concurrency::extent<2> eIn(nJobs, uInDWSize);
Concurrency::extent<2> eOut(nJobs, arrChData.GetChannelPackedLen());
array_view<DWORD, 2> viewOut(eOut, arrChData.m_arrChannels);
array_view<DWORD, 2> viewIn(eIn, arrCompData);
concurrency::parallel_for_each(begin(a), end(a), [&](int vch)
{
vector<DWORD>::pointer ptr = (LPDWORD)viewIn(vch).data();
LPDWORD bufCompIn = (LPDWORD)ptr;
ptr = viewOut(vch).data();
LPDWORD bufExpandedIn = (LPDWORD)ptr;
if(ConditionNotOk())
{
// Copy raw data bufCompIn to bufExpandedIn
// Works fine, but not the best way, I suppose:
memcpy(bufExpandedIn, bufCompIn, uAmount);
// Raises exception:
//viewIn(vch).copy_to(viewOut(vch));
}
else
{
// Some data processing here
}
});
}
答案 0 :(得分:0)
与parallel_for_each
无关,看起来它是array_view::copy_to
的已知错误。请参阅以下帖子:
Curiosity about concurrency::copy and array_view projection interactions
您可以使用明确的view_as()
来解决此问题。我相信你的情况你的代码应该是这样的。
viewIn(vch).copy_to(viewOut(vch));
// Becomes...
viewIn[vch].view_as<1>(concurrency::extent<1>(uInDWSize)).copy_to(viewOut(vch));
我无法编译您的示例,因此无法对此进行验证,但我能够从类似代码中获取异常并使用view_as()
进行修复。
如果要在C ++ AMP内核中复制数据,则需要在一系列线程上执行赋值操作。以下代码将source
的前500个元素复制到较小的dest
数组中。
array<int, 1> source(1000);
array<int, 1> dest(500);
parallel_for_each(source.extent, [=, &source, &dest](index<1> idx)
{
if (dest.extent.contains(idx))
dest[idx] = source[idx];
});
答案 1 :(得分:0)
这是我的错。在原始代码中,viewOut(vch)的范围比viewIn(vch)范围稍大。使用这种方式,它会引发异常&#39; runtime_exception&#39;。捕获它时,它提供以下消息:xcp.what()=&#34;由于范围不匹配而无法复制&#34;。
我修复了代码替换原始代码:viewIn(vch).copy_to(viewOut(vch).section(viewIn(vch).extent)); 它只复制源范围,这就是我需要的。但只能编译没有限制AMP。