【发布时间】:2016-10-19 20:45:07
【问题描述】:
我正在使用 C++ amp 以波兰表示法计算 (+ x y) 形式的数学表达式。现在棘手的部分是表达式以树的形式给出,我将其“编译”成线性指令,基本上使用树的广度遍历将给我一个指令列表的属性,这些指令可以向后迭代以确保每个孩子节点将在其父节点之前被评估。
struct amp_instruction
{
op_code opcode; // add, sub, variable, etc
int index; // index of first child
double value; // for constants
double weight; // for variables
std::string label; // node label
std::shared_ptr<concurrency::array_view<double, 1>> data; // amp data
};
在创建指令时,我这样分配数据字段:
instr.data = make_shared<array_view<double, 1>>(n);
那么,我的评价是:
array_view<double, 1> amp_interpreter::evaluate(vector<amp_instruction>& instructions)
{
for (auto &it = rbegin(instructions); it != rend(instructions); ++it)
{
switch (it->opcode)
{
case ADD:
{
array_view<double, 1> a = *instructions[it->index].data;
array_view<double, 1> b = *instructions[it->index + 1].data;
parallel_for_each(a.extent, [=](index<1> i) restrict(amp)
{
a[i] += b[i];
});
it->data = instructions[it->index].data;
break;
}
// other cases... //
case VARIABLE:
{
array_view<double, 1> a = *it->data;
array_view<const double, 1> v = *gpu_data[it->label];
double weight = it->weight;
parallel_for_each(a.extent, [=](index<1> i) restrict(amp)
{
a[i] = v[i] * weight;
});
break;
}
default: break;
}
}
return *instructions[0].data;
}
其中 gpu_data 是一个映射,其中包含我的变量的初始值(例如,最多可达一百万)。所以想法是,为每个变量获取值(缓存在 gpu_data 中),应用权重值,并将结果保存在相应 amp_instruction 的数据字段中。然后,数据从子级传递到父级,以减少 gpu 上的内存分配。
现在,当我在调试模式下编译我的程序时,这段代码可以正常工作,为 1000 个树表达式使用约 1gb 的常量内存,为每个树变量使用 1M 值。它还会产生正确的值,因此逻辑有效。但在发布模式下,内存使用量会飙升至 10-20GB。这只发生在默认加速器上,这是我的 radeon r9 fury。基本的渲染器加速器没有这个问题。
我的硬件是 i7 4790k,32gb ddr3,radeon r9 fury。这可能是驱动程序问题吗?或者,也许我没有按预期使用 c++ amp?我真的希望有人能对这个问题有所了解,因为这个错误使整个方法无法使用。
谢谢。
【问题讨论】:
-
使用较小的测试用例可能更容易调试 :-)
-
您能否将所有数字
ai成员初始化为零?更一般地说,也许您可以为您的amp_instruction类创建一个默认构造函数,它将所有整数和双精度字段归零?调试/发布行为差异通常来自于发布中的单元化变量/调试中的 0。 -
我试过了,但没有任何改变。该代码还针对同一事物的标准(仅限 cpu)实现进行了验证,并且它始终产生正确的值。唯一的问题是它在释放模式下会泄漏内存。
标签: c++ memory-leaks visual-studio-2015 c++-amp