2016-10-19 1 views
-2

Я использую усилитель 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.

Теперь этот код отлично работает при компиляции моей программы в режиме отладки с использованием постоянной памяти около ~ 1gb для 1000 выражений дерева и значений 1M для каждой переменной дерева. Он также дает правильные значения, поэтому логика работает. Но в режиме деблокирования использование памяти достигает 10-20 гб. Это происходит только с ускорителем по умолчанию, который является моим radeon r9 fury. У этого основного ускорителя нет такой проблемы.

Мое оборудование i7 4790k, 32gb ddr3, radeon r9 fury. Это может быть проблема с драйвером? Или, может быть, я не использую усилитель C++, как предполагалось? Я действительно надеюсь, что кто-то может пролить свет на этот вопрос, поскольку эта ошибка делает весь подход непригодным.

Спасибо.

+0

Это может быть проще отладить с меньшим тестовым случаем :-) – AndyG

+1

Вы могли бы инициализировать до нуля все числовые члены 'ai'? в общем, возможно, вы могли бы создать конструктор по умолчанию для вашего класса 'amp_instruction', который обнуляет все целые и двойные поля? Отладка/устранение различий в поведении часто происходит от унифицированных переменных в release/0 при отладке. –

+0

Я пробовал, но ничего не меняет. Код также был проверен против стандартной (только для процессора) реализации одной и той же вещи, и он всегда производит правильные значения. Единственная проблема заключается в том, что он утечки памяти в режиме деблокирования. –

ответ

0

Я не смог определить источник утечки памяти, но это определенно происходит из среды выполнения. Изменение «Runtime Library» в параметрах проекта из «Многопоточной DLL (/ MD)» на «Многопотоковая DLL (/ MDd) отладки» устраняет утечку памяти.

 Смежные вопросы

  • Нет связанных вопросов^_^