Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Здравствуйте, Mazay, Вы писали:
M>>Программа при запуске выделяет большой кусок памяти (512 ГБ) под массив double-ов. Сейчас это делается вот так:
PD>Точно Гигабайт ? 512 ? А сколько RAM на машине ?
Один террабайт. Там кроме этого мегавектора есть ещё несколько помельче. В пике получается около 85% памяти занято.
Главное гармония ...
Re[2]: Как ускорить выделение большого куска памяти?
Здравствуйте, ononim, Вы писали:
M>>Программа при запуске выделяет большой кусок памяти (512 ГБ) под массив double-ов. Сейчас это делается вот так: M>>
M>>vector <double> vect(N);
M>>
M>>Это занимает около 10 минут времени при 100% загрузке одного ядра. M>>Что там вообще менеджер кучи так долго делает? O>...свопится, наверное
Не Там террабайт памяти. В своп точно не уходит.
Главное гармония ...
Re[3]: Как ускорить выделение большого куска памяти?
Здравствуйте, Mazay, Вы писали:
PD>>Точно Гигабайт ? 512 ? А сколько RAM на машине ?
M>Один террабайт. Там кроме этого мегавектора есть ещё несколько помельче. В пике получается около 85% памяти занято.
Под Windows решение простое — VirtualAlloc. Под линукс см. здесь
Здравствуйте, Mazay, Вы писали:
M> Что там вообще менеджер кучи так долго делает?
А точно менеджер кучи тупит, а не забивание этой памяти дефолтными нулями? Цапните её стандартным маллоком, он ничем не заполняет. Если не поможет — вручную ммапом.
И общий совет при таких размерах: включите HugeTLB хотя бы двухметровое, а можно попробовать и гигабайтное.
Насчёт не свопится — тоже лучше проверить, оно и профилактически может, отключите все своп-разделы.
В любом случае очень подозрительно, даже если заполнение, скорость меньше гига в секунду — это странно.
Вы точно не под валгриндом пускаетесь? Или у Вас винда?
Здравствуйте, Mazay, Вы писали:
M>Программа при запуске выделяет большой кусок памяти (512 ГБ) под массив double-ов. Сейчас это делается вот так: M>vector <double> vect(N); M>Это занимает около 10 минут времени при 100% загрузке одного ядра.
Когда делаете так vector <double> vect(N); запускается это
что быстро выполнится при больших N не может.
M>Можно ли как-то ускорить это дело? Распараллелить например. Что там вообще менеджер кучи так долго делает?
Да, делайте просто malloc() без этих stl дурковатостей.
Здравствуйте, smeeld, Вы писали:
S>что быстро выполниться при больших N не может.
Интересно, что этот construct делает, и можно ли его попросить этого не делать?
По крайней мере, new раньше спокойно оставлял примитивные типы неинициализированными, а vector так не умеет?
S>Да, делайте просто malloc() без этих stl дурковатостей.
Можно с придурковатостями, в shared_ptr засунуть, но после malloc
Другой вопрос — нужен ли в программе этот здоровый массив? Если его нулями заливает 10 минут, то какое время займёт его обычное использование? Если 10 минут — ничтожная доля в общем времени, то имеем классическую причину всех зол, по Кнуту. Если доля существенная, то массив как таковой практически не исползуется, только небольшие его участки, и его хорошо бы заменить на подходящую структуру меньшего размера.
А если его таки надо забить изначально нулями, то может быть проще его в .bss завести, система сама инициализирует, если умная — аппаратно. Ну или правда через OpenMP распараллелить, обычно в машине несколько каналов к памяти, может в несколько раз ускориться. Или memset позвать, вдруг он что-то знает
Re[3]: Как ускорить выделение большого куска памяти?
Если его заменить пустышкой, то это всё равно не избавит от самого цикла, к тому же, vector станет
кастрированным, вся инициализация элементов в push*, emplace*, insert проводится через __alloc.construct()
Re[2]: Как ускорить выделение большого куска памяти?
Здравствуйте, cures, Вы писали: C>В любом случае очень подозрительно, даже если заполнение, скорость меньше гига в секунду — это странно.
Оно примерно так и работает 512ГБ ~600 секунд
Re[3]: Как ускорить выделение большого куска памяти?
Здравствуйте, cures, Вы писали: C>то имеем классическую причину всех зол, по Кнуту. Если доля существенная, то массив как таковой практически не исползуется, только небольшие его участки, и его хорошо бы заменить на подходящую структуру меньшего размера.
Там по ходу программа запускается 10 минут. А учитывая 1ТБ памяти, оно еще и сервер. А значит программа, скорее всего — служба.
Если все так, то оптимизировать уже пора
Re[4]: Как ускорить выделение большого куска памяти?
Здравствуйте, smeeld, Вы писали:
S>Если его заменить пустышкой, то это всё равно не избавит от самого цикла,
Пустой цикл выкинется оптимизатором, да и 64 миллиарда итераций не займут 10 минут, от силы — одну
S> к тому же, vector станет кастрированным, вся инициализация элементов в push*, emplace*, insert проводится через __alloc.construct()
Это же чудесно! Можно будет пользоваться как нормальным массивом.
А если не совсем пустышкой, скажем, перекрыть размещающий new для конкретного типа double?
Re[4]: Как ускорить выделение большого куска памяти?
Здравствуйте, MTimur, Вы писали:
MT>Там по ходу программа запускается 10 минут. А учитывая 1ТБ памяти, оно еще и сервер. А значит программа, скорее всего — служба. MT>Если все так, то оптимизировать уже пора
Если служба, то работает 24*7, нет смысла оптимизировать запуск
Да и где это виданы самописные службы на терабайт?
"Это служба — так уж служба, тут нужна моя вся дружба!"
Но всё же хотелось бы послушать начальника транспортного цеха.
MT> Оно примерно так и работает 512ГБ ~600 секунд
Обычно скорость работы с памятью не меньше 2 гигов в секунду, даже в один канал. Тут видимо ещё цикл не оптимизировался и мимо ТЛБ всё время ходят.
Здравствуйте, cures, Вы писали:
C>Это же чудесно! Можно будет пользоваться как нормальным массивом.
Зачем тогда vector, когда достаточно просто массива? Или всем отделом смеяться будут? Типа modern C++ не осилил.
И цикл будет не пустой, Вы ведь не реализацию std::vector будете корректировать, а просто назначите свой allocator,
вместо дефолтного, с пустым методом construct, который и будет вызываться в цикле, и пустота которого предотвратит
выделение реальных страничных фреймов в ядре в момент создания vector.
C>А если не совсем пустышкой, скажем, перекрыть размещающий new для конкретного типа double?
Это и есть пустышка, если не будет производиться запись любого значения по адресу std::__addressof(*__cur).
Re[5]: Как ускорить выделение большого куска памяти?