Класс объекта внутри или снаружи arallel_for / parallel_for_each?
Я изучал параллельные циклы (C++11) и тестировал их в MS visual Studio 2013. Я ясно представляю их (lambdas esp.), Которые довольно круты.
Но меня беспокоит то, что мне нужно вызвать функцию, которая выполняет простую евклидову меру расстояния. Функция сама по себе ясна, но я должен переместить функцию в класс с именем EuclideanDistance и выполнить евклидову математику внутри функции Match(vectorA,vectorB) для двух векторов, что просто является вычислением некоторой нормы (...). И возвращает значение с плавающей запятой.
Теперь, как мне это сделать в цикле parallel_for / parallel_foreach? Должен ли я создать объект класса внутри цикла или сохранение объекта класса вне цикла вызовет несоответствия? Если я правильно понял про параллельные циклы, то функция, над которой он работает, в основном является чистой копией для каждого запущенного потока. Это происходит в случае функций класса? Моя догадка нет! Если я не создаю объект внутри класса, как показано во втором фрагменте кода.
Например, для удобства чтения я держу код в сокращенном виде.
vectorA; // Floating point array of 1024 entries.
concurrent_queue vectorQ; // each entry in the queue is a 1024 array
EuclideanDistance euclid;
parallel_for_each(begin,end,[&](auto item)
{
auto distance = euclid.Match(vectorA,item);
});
Или это будет правильный способ сделать это?
parallel_for_each(begin,end,[&](auto item)
{
EuclideanDistance euclid;
auto distance = euclid.Match(vectorA,item);
});
Весь класс - не более чем одна функция.
class EuclideanDistance
{
public:
float Match(vectorA,vectorB)
{
return norm(vectorA,vectorB);
}
};
Любые подводные камни будут высоко оценены!
1 ответ
Вы правы в том, что если вы определите свой EuclideanDistance
объект за пределами parallel_for_each
лямбда-тело, оно будет разделено между всеми рабочими потоками, выполняющими parallel_for_each
, Это было бы проблемой, если ваш Match()
Функция имела побочные эффекты, влияющие на общее состояние в вашем EuclideanDistance
объект, но в этом случае он, скорее всего, определит объект внутри лямбды (что даст каждому выполнению тела цикла свой собственный локальный экземпляр) будет иметь отличные результаты от определения его снаружи.
Пока любые функции, которые вы вызываете на EuclideanDistance
У объекта нет побочных эффектов / не изменяйте общее состояние, тогда вы можете использовать один объект, определенный вне лямбда-выражения. Если бы вы вызывали функции с побочными эффектами, вам нужно было бы выполнить собственную синхронизацию, которая, вероятно, повлияла бы на прирост производительности parallel_for_each
значительно.