Я распараллеливаю следующий блок, чтобы вычислить число смертельных несчастных случаев в неделю для набора данных переменного размера (0,5M, 1M, 2M и т. Д. c.), Хранящегося внутри localRows
, который является вектором , Общие переменные local_lethAccPerWeek, local_accAndPerc, local_boroughWeekAcc
- это массивы, хранящиеся непрерывно (например, int local_lethAccPerWeek[NUM_YEARS][NUM_WEEKS_PER_YEAR] = {};
).
// [2] Data processing
procBegin = MPI_Wtime();
cout << "[Proc. " + to_string(myrank) + "] Started processing dataset..." << endl;
omp_set_num_threads(num_omp_threads);
int cfIndex, brghIndex;
// Every worker will compute in the final datastructure the num of lethal accidents for its sub-dataset and then Reduce it to allow the master to collect final results
#pragma omp parallel for default(shared) schedule(dynamic) private(cfIndex, brghIndex)
for (int i = 0; i < my_num_rows; i++)
{
int lethal = (localRows[i].num_pers_killed > 0) ? 1 : 0;
string borough = string(localRows[i].borough);
int week, year, month = 0;
if (lethal || !borough.empty())
{
week = getWeek(localRows[i].date);
year = getYear(localRows[i].date);
month = getMonth(localRows[i].date);
// If I'm week = 1 and month = 12, this means I belong to the first week of the next year.
// If I'm week = (52 or 53) and month = 01, this means I belong to the last week of the previous year.
if (week == 1 && month == 12)
year++;
else if ((week == 52 || week == 53) && month == 1)
year--;
year = year - 2012;
week = week - 1;
}
/* Query1 */
if (lethal)
#pragma omp atomic
local_lethAccPerWeek[year][week]++;
/* Query2 */
for (int k = 0; k < localRows[i].num_contributing_factors; k++)
{
cfIndex = cfDictionary.at(string(localRows[i].contributing_factors[k]));
#pragma omp critical(query2)
{
(local_accAndPerc[cfIndex].numAccidents)++;
(local_accAndPerc[cfIndex].numLethalAccidents) += lethal;
}
}
/* Query3 */
if (!borough.empty()) // if borough is not specified we're not interested
{
brghIndex = brghDictionary.at(borough);
#pragma omp critical(query3)
{
local_boroughWeekAcc[brghIndex][year][week].numAccidents++;
local_boroughWeekAcc[brghIndex][year][week].numLethalAccidents += lethal;
}
}
}
procDuration = MPI_Wtime() - procBegin;
Я испытываю странное поведение, поскольку увеличение потоков omp приводит к увеличению времени выполнения. Я знаю, что порождающие потоки увеличивают накладные расходы из-за переключения контекста и т. Д. и в некоторых случаях может быть более гладким позволить одному потоку выполнять работу, но я не вижу, как распараллеливание операции такого типа (это просто увеличение в разделе atomi c) может быть хуже. Я также пытался из любопытства изменить расписание, но, конечно, это не помогло.
Я спрашиваю вас, так как вы можете увидеть что-то, что мне не хватает. Заранее благодарим и, пожалуйста, прокомментируйте, если вам нужна дополнительная информация.