Я новичок в многопоточном программировании, и я знаю, что несколько подобных вопросов задавались ранее на SO, однако я хотел бы получить ответ, определяющий c мой код.
У меня есть два вектора объектов (v1 и v2), через которые я хочу l oop, и в зависимости от того, соответствуют ли они некоторым критериям, добавьте эти объекты в один вектор, например:
Не многопоточный регистр
std::vector<hobj> validobjs;
int length = 70;
for(auto i = this->v1.begin(); i < this->v1.end() ;++i) {
if( !(**i).get_IgnoreFlag() && !(**i).get_ErrorFlag() ) {
hobj obj(*i, length);
validobjs.push_back(hobj);
}
}
for(auto j = this->v2.begin(); j < this->v2.end() ;++j) {
if( !(**j).get_IgnoreFlag() && !(**j).get_ErrorFlag() ) {
hobj obj(*j, length);
validobjs.push_back(hobj);
}
}
Многопоточный регистр
std::vector<hobj> validobjs;
int length = 70;
#pragma omp parallel
{
std::vector<hobj> threaded1; // Each thread has own local vector
#pragma omp for nowait firstprivate(length)
for(auto i = this->v1.begin(); i < this->v1.end() ;++i) {
if( !(**i).get_IgnoreFlag() && !(**i).get_ErrorFlag() ) {
hobj obj(*i, length);
threaded1.push_back(obj);
}
}
std::vector<hobj> threaded2; // Each thread has own local vector
#pragma omp for nowait firstprivate(length)
for(auto j = this->v2.begin(); j < this->v2.end() ;++j) {
if( !(**j).get_IgnoreFlag() && !(**j).get_ErrorFlag() ) {
hobj obj(*j, length);
threaded2.push_back(obj);
}
}
#pragma omp critical // Insert local vectors to main vector one thread at a time
{
validobjs.insert(validobjs.end(), threaded1.begin(), threaded1.end());
validobjs.insert(validobjs.end(), threaded2.begin(), threaded2.end());
}
}
В не многопоточном случае мое общее время, потраченное на выполнение операции, примерно в 4 раза быстрее, чем в многопоточном случае (~ 1,5 с против ~ 6 с).
Я знаю, что критическая директива #pragma omp является падением производительности, но, поскольку я заранее не знаю размер вектора validob js, я не могу полагаться на случайную вставку index.
Итак, вопросы:
1) Подходит ли этот вид операций для многопоточности?
2) Если да, то 1) - выглядит ли многопоточный код разумным?
* 1 028 *
3) Могу ли я что-нибудь сделать, чтобы улучшить производительность, чтобы получить скорость быстрее, чем в случае без ниток? Дополнительная информация:
- Приведенный выше код вложен в гораздо большую кодовую базу, которая выполняет 10 000–100 000 итераций (эта l oop не использует многопоточность). Я знаю, что порождающие потоки также влекут за собой снижение производительности, но насколько я знаю, эти потоки поддерживаются до тех пор, пока приведенный выше код снова не будет выполняться, каждая итерация
omp_set_num_threads
установлена в 32 (I '). м на 32-ядерном компьютере). - Ubuntu, g cc 7.4
Ура!