c ++ amp — Как ограничить количество потоков, выполняющих действие в C ++ AMP

Я выполняю серию вычислений для большого количества потоков, используя C ++ AMP. Последний шаг вычисления — это сокращение результата, но только для ограниченного числа потоков. Например, если результат вычисления ниже порогового значения, установите для этого результата значение 0, НО делать это только для максимум X потоков. По сути, это общий счетчик, но также общая условная проверка.

Любая помощь приветствуется!

2

Решение

Мое понимание вашего вопроса — следующий псевдокод, выполняемый каждым потоком:

auto result = ...
if(result < global_threshold)  // if the result of the calculation is below a threshold
if(global_counter++ < global_max)  // for a maximum of X threads
result = 0;  // then set the result to 0
store(result);

Затем я предполагаю, что оба global_threshold а также global_max не изменяется во время вычислений (т.е. между parallel_for_each начать и закончить), поэтому самый элегантный способ их прохождения — лямбда-захват.

С другой стороны, global_counter четко меняет значение, поэтому оно должно находиться в модифицируемой памяти, разделяемой между всеми потоками, эффективно array<T,N> или же array_view<T,N>, Поскольку потоки, увеличивающие этот объект, не синхронизированы, операция должна быть выполнена с использованием атомарной операции.

Вышеприведенный код переводится в следующий код C ++ AMP (я использую синтаксис Visual Studio 2013, но его легко переносить обратно в Visual Studio 2012):

std::vector<int> result_storage(1024);
array_view<int> av_result{ result_storage };

int global_counter_storage[1] = { 0 };
array_view<int> global_counter{ global_counter_storage };

int global_threshold = 42;
int global_max = 3;

parallel_for_each(av_result.extent, [=](index<1> idx) restrict(amp)
{
int result = (idx[0] % 50) + 1; // 1 .. 50
if(result < global_threshold)
{
// assuming less than INT_MAX threads will enter here
if(atomic_fetch_inc(&global_counter[0]) < global_max)
{
result = 0;
}
}
av_result[idx] = result;
});

av_result.synchronize();

auto zeros = count(begin(result_storage), end(result_storage), 0);
std::cout << "Total number of zeros in results: " << zeros << std::endl
<< "Total number of threads lower than threshold: " << global_counter[0]
<< std::endl;
1

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector