2015-08-25 3 views
2

У меня есть большой вектор элементов, отсортированных по одному из их полей, например. атрибут затрат, и я хочу немного обработать каждый из этих элементов, чтобы найти максимальное значение другого атрибута ... Ограничение здесь заключается в том, что мы не можем использовать элемент для вычисления максимального значения, если стоимость этого элемента превышает какая-то произвольная цена.break sub task of parallel_for_each

Сингл резьбовая для цикла выглядит следующим образом:

auto maxValue = -MAX_FLT; 
for(const auto& foo: foos) { 

    // Break if the cost is too high. 
    if(foo.cost() > 46290) { 
     break; 
    } 

    maxValue = max(maxValue , foo.value()); 
} 

Я был в состоянии несколько трансформируют это в parallel_for_each. (Отказ от ответственности: Я новичок в госзакупках.)

combinable<float> localMaxValue([]{ return -MAX_FLT; }); 

parallel_for_each(begin(foos), end(foos), [&](const auto& foo) { 

    // Attempt to early out if the cost is too high. 
    if(foo.getCost() > 46290) { 
     return; 
    } 

    localMaxValue.local() = max(localMaxValue.local(), foo.getValue()); 
} 

auto maxValue = localMaxValue.combine(
    [](const auto& first, const auto& second) { 
     return max<float>(first, second); 
    }); 

Оператор возврата внутри parallel_for чувствует себя неэффективным, поскольку он по-прежнему выполняет над каждый пункт, и в этом случае, вполне возможно, что parallel_for может закончиться итерация несколько частей вектора, стоимость которых слишком высока.

Как я могу воспользоваться тем фактом, что вектор уже отсортирован по стоимости?

Я изучил использование маркера отмены, но этот подход кажется неправильным, поскольку это приведет к отмене всех подпрограмм parallel_for, что означает, что я могу получить неправильное максимальное значение.

Есть ли что-то вроде маркера отмены, который может отменить эту конкретную подзадачу parallel_for, или есть лучший инструмент, чем parallel_for в этом случае?

ответ

1

Если вектор отсортирован по цене, вы можете перебирать только предметы, стоимость которых ниже, чем предел стоимости.

Если стоимость х. найти первый элемент итератора, который равен или больше x. вы можете использовать std :: lower_bound. , то вы используете свой parallel_for_each от начала вектора до итератора, который вы нашли.

combinable<float> localMaxValue([]{ return -MAX_FLT; }); 

//I'm assuming foos is std::vector. 
int cost_limit = 46290; 
auto it_end = std::lower_bound(foos.begin(), foos.end(), cost_limit, [](const auto& foo, int cost_limit) 
{ 
    return foo.getCost() < cost_limit; 
}); 

parallel_for_each(foos.begin(), foos.end(), [&](const auto& foo) {  
    localMaxValue.local() = max(localMaxValue.local(), foo.getValue()); 
} 

auto maxValue = localMaxValue.combine(
    [](const auto& first, const auto& second) { 
     return max<float>(first, second); 
    }); 
+0

Я мог видеть, как это будет хорошо работать для этого примера; практическая проблема, которую я пытаюсь решить, немного отличается, хотя и я не уверен, что идентификация индекса максимальной стоимости до параллелизма закончится тем, что сэкономит время. Тем не менее стоит попробовать. Спасибо за предложение. – user8709