我正在使用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)實現進行了驗證,並且它始終生成正確的值。唯一的問題是它在釋放模式下泄漏內存。 –