我正在使用C++放大器以波兰表示法评估形式(+ x y)的数学表达式。现在棘手的部分是表达式是以树的形式给出的,我将它们编译成线性指令,基本上使用的属性是树的宽度遍历会给我一个可以向后迭代的指令列表,以确保每个孩子节点将在它的父节点之前被评估。使用C++放大器发生内存泄漏,但仅限于发布模式
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个树表达式和1M值的恒定内存大约为1GB。它也产生正确的值,所以逻辑起作用。但在发布模式下,内存使用量达到10-20gb。这只会发生在默认的加速器上,这是我的radeon r9愤怒。基本的渲染器加速器没有这个问题。
我的硬件是i7 4790k,32gb ddr3,radeon r9愤怒。这可能是一个驱动程序问题吗?或者,也许我没有按照预期使用C++放大器?我真的希望有人能够解释这个问题,因为这个错误会导致整个方法无法使用。
谢谢。
这可能更容易用较小的测试案例进行调试:-) – AndyG
您是否可以初始化所有数字的'ai'成员为零?更一般地说,也许你可以为你的'amp_instruction'类创建一个默认的构造函数,它将所有整数和双字段清零?调试/发布行为差异通常来自调试中release/0中的单元化变量。 –
我试过了,但它没有改变任何东西。该代码也针对同一事物的标准(仅cpu)实现进行了验证,并且它始终生成正确的值。唯一的问题是它在释放模式下泄漏内存。 –