Вызов функции внутри OpenMP для цикла - PullRequest
0 голосов
/ 28 мая 2020

У меня есть следующее для l oop, которое содержит внутри себя вызов частной функции:

for (i = 0; i < N; ++i)
    dates[i] = to_time_t(&string_dates[i][0]);

to_time_t просто преобразует строку (e.g.: "18/03/2007") в метку времени, и она делает это с помощью mktime(), что очень медленно. Фактически, это только для l oop занимает больше всего времени для любого другого кода в программе. Чтобы исправить это, я пытаюсь применить OpenMP к l oop, например:

#pragma omp parallel for private(i)
for (i = 0; i < N; ++i)
    dates[i] = to_time_t(&string_dates[i][0]);

Мои знания OpenMP ограничены, но я предполагаю, что каждый элемент массива dates никогда не используется двумя потоками одновременно, поскольку i является частным. То же самое относится к string_dates. Но когда я запускаю этот код, производительность на самом деле хуже, поэтому я, должно быть, делаю что-то не так, я просто этого не вижу. Любая помощь приветствуется!

Изменить: я должен был включить код to_time_t с самого начала.

time_t to_time_t(const string * date) {
    struct std::tm tm = {0};

    istringstream ss_tm(*date);
    ss_tm >> get_time(&tm, "%m/%d/%Y");

    return mktime(&tm);
}

1 Ответ

1 голос
/ 29 мая 2020

Проблема в mktime(), которая имеет побочный эффект для всего процесса. На странице руководства :

Вызов mktime () также устанавливает внешнюю переменную tzname с информацией о текущем часовом поясе.

mktime() внутренние вызовы tzset(). Последний сериализуется через блокировку мьютекса, но что действительно замедляет его в многопоточном случае, так это постоянная очистка кеша. Когда вызов tzset() потоком, запущенным на конкретном ядре ЦП, записывает в tzname, это делает недействительными кеши всех других ядер, вынуждая потоки, выполняющиеся на этих ядрах, обращаться к более высоким уровням кеша или даже к основной памяти в следующий раз, когда будет вызов mktime().

Вам нужно будет найти или написать эквивалент mktime(), который не изменяет глобальное состояние. Или просто придерживайтесь последовательного выполнения этой части кода. Совершенно нормально вызывать mktime() одновременно в нескольких последовательных процессах (например, в чистом приложении MPI).

...