Можно ли распараллелить удаление выделения памяти с помощью openmp? (С++)

int **something = new int *[N];
for(int n = 0; n < N; n++)
    something[n] = new int[M];

#pragma omp parallel for
for (int n = 0; n < N; n++)
    delete[] something[n];
delete[] something;

Могу ли я распараллелить процесс удаления таким образом?

Убийца OOM Linux убил мой процесс после довольно большого количества циклов. Я пытался выяснить, где происходит утечка памяти, но не нашел, где. Я не уверен, хорошо ли работал этот процесс удаления цикла for или нет.

Но почему? Экономит ли распараллеливание этой операции достаточно времени, чтобы обойти настройку и демонтаж?

Thomas Matthews 07.02.2023 19:01

Ваша куча свободна от блокировки? Было бы иронично, если бы в куче был мьютекс, который бы сериализовал операции.

Eljay 07.02.2023 19:02

Стыдно признаться, что потребовалось всего 20 лет, чтобы осознать шутку, лежащую в основе имени командира боевых дроидов OOM-9.

user4581301 07.02.2023 19:15

Убийца OOM Linux убил мой процесс после довольно большого количества циклов. Как в этом поможет распараллеливание delete вызовов?

Andrew Henle 07.02.2023 19:19

Возможно, вам нужно изучить использование виртуальной памяти и увеличить размер свопа.

drescherjm 07.02.2023 19:24

Извините за мой плохой запутанный вопрос. Я только что зарегистрировался на stack overflow и начал программировать всего месяц назад. Даже не английский пользователь. Я сделал проект, прогнал его на ~100000 циклов, и он был убит. Поэтому я попытался выяснить, где произошла утечка памяти, и у меня возникли сомнения по поводу этой части кода. Я не знал, что распараллеливание освобождения памяти на самом деле не помогает.

Mingi Kim 08.02.2023 03:35

Использование new считается плохим C++. Почему вы не используете стандартные контейнеры, которые гораздо более безопасны для памяти?

Victor Eijkhout 10.02.2023 00:55
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
7
78
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Обычно это нормально. Стандартная куча (g)libc должна быть потокобезопасной; в противном случае было бы вообще невозможно писать многопоточные программы. Также можно выделить буфер в одном потоке и освободить его в другом.

Распараллеливание распределения кучи не даст вам большого ускорения, но я подозреваю, что вы спрашиваете не потому, что хотите ускорить (де-)распределение, а скорее потому, что у вас есть какой-то другой параллельный код, который выделяет и освобождает некоторые буферы.

Чтобы найти утечку, попробуйте запустить программу с помощью valgrind.

Кроме того, рассмотрите возможность вызова malloc_trim(0); после освобождения больших объемов памяти. Это заставляет glibc освобождать неиспользуемую память обратно в операционную систему, вместо того, чтобы удерживать всю ее для последующего выделения.

Распараллеливание выделений на самом деле помогло бы, поскольку разные потоки имеют разные области памяти. Так что это можно распараллелить. Я только что проверил это и обнаружил фактор 4 в своей системе. Простое распараллеливание освобождения не поможет, так как каждый поток будет конкурировать за блокировку с одной ареной, где все было выделено.

Homer512 07.02.2023 19:13

@ Homer512 Распараллеливание выделений действительно помогло бы, поскольку разные потоки имеют разные области памяти. Только в том случае, если выделения недостаточно велики, чтобы их можно было заменить на mmap() или вызвать повторные вызовы [s]brk(), чтобы получить больше памяти. Любой из них потребует создания и сопоставления новых страниц виртуальных машин, ни одна из которых не может быть многопоточной.

Andrew Henle 07.02.2023 19:21

@AndrewHenle Правда, это зависит от размера

Homer512 07.02.2023 21:00

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

Mingi Kim 08.02.2023 03:42

Другие вопросы по теме