Здравствуйте, chaotic-good, Вы писали:
M>>Компилятор — g++ 4.8 M>>OS — CentOS 7
M>>Можно ли как-то ускорить это дело? Распараллелить например. Что там вообще менеджер кучи так долго делает?
CG>Смотря что за железка, если там NUMA (что скорее всего имеет место быть, так как массив памяти очень уж большой), то выделять (и инициализировать) одним большим куском столько памяти — бессмысленно. Каждая NUMA нода должна выделять память, с которой она потом будет работать преимущественно самостоятельно, так как менеджер памяти в ОС — NUMA aware и будет давать потоку память из той же ноды. Можно выделить большой кусок виртуальной памяти через valloc или mmap и потом инициализировать те куски, с которыми ты будешь работать из разных потоков этими же потоками и тогда менеджер памяти, по идее, должен раздать им страницы физической памяти из соответствующих NUMA-нод.
Да, конечно NUMA. На Intel QPI.
Обязательно выделять память через valloc? malloc или new дадут другое поведение?
CG>Можно, например, завести битовый массив, каждый бит которого соответствовал бы странице памяти из этих 512-ти ГБ, если поток пытается обратиться к какой-либо странице, то он сначала должен проверить соответствующий бит а затем, если этот бит равен 0 — инициализировать соответствующий участок памяти (+ синхронизация этого всего, вероятно оптимистичная, так как памяти дохрена и конфликты будут редким явлением). Это позволит отложить инициализацию и, соответственно, не выделять физическую память сразу. Естественно, нужно сделать так, чтобы повторное обращение к тому же участку памяти с высокой долей вероятности происходило из того же потока.
Эта теория понятна. Просто там такой алгоритм, что каждое ядро со всей памятью работает. Если бы можно было локальности какие-то выделить, это всё уже давно бы на MPI кластерах посчитали. Со временем, конечно, займусь оптимизацией.