Почему пропускная способность для отправки MPI между сокетами больше пропускной способности памяти?
Я провел тест osu_mbw_mr (из микробенчур OSU) на узле Haswell в Кори в NERSC и получил странные результаты, которые я не смог объяснить.
Узел имеет два сокета, каждый из которых имеет 16-ядерный процессор Intel Xeon E5-2698 v3. Два процессора связаны QPI. Подробности узла и процессора можно найти здесь и здесь.
Если я не ошибаюсь, максимальная пропускная способность памяти узла составляет 68 ГБ / с x 2 ЦП = 136 ГБ / с, а максимальная пропускная способность QPI составляет 9,6 ГТ / с x 2 ссылки x 2 байта / ссылка = 38,4 ГБ / с, двунаправленно. Я также измерил пропускную способность памяти с помощью STREAM. Пропускная способность копирования составляет около 110 ГБ / с, что близко к теоретическому. Это прекрасно.
Я запустил osu_mbw_mr с 32 рангами MPI на одном узле и поместил первые 16 рангов в сокет 0, а следующие 16 рангов в сокет 1.
В osu_mbw_mr каждый ранг выделяет буфер отправки (s_buf) и буфер приема (r_buf), а затем инициализирует их (поэтому я предполагаю, что буферы имеют сходство с их доменом NUMA при первом касании). Имея 32 ранга, ранги 0~15 отправляют фиксированное количество сообщений (размер окна) вплотную в парные ранги приема, то есть 16~31. Я использовал Cray MPICH. Я думаю, что независимо от того, как реализован MPI, чистый эффект - это "копирование данных из s_buf (через ссылки QPI) в r_buf".
Ниже мой результат теста. Я не понимаю, почему полосы пропускания для сообщений размером 8 КБ, 16 КБ и т. Д. Настолько велики и внезапно уменьшаются до 2 МБ сообщений. Пропускные способности больше, чем пропускная способность QPI, даже чем пропускная способность DRAM. В моей теории, пропускная способность должна быть ограничена половиной пропускной способности QPI (19,2 ГБ / с), так как мы отправляли данные в однонаправленном режиме от сокета 0 до 1.
Что случилось? Благодарю.
# OSU MPI Multiple Bandwidth / Message Rate Test v5.4.0
# [ pairs: 16 ] [ window size: 64 ]
# Size MB/s Messages/s
1 47.55 47550478.99
2 94.74 47371180.52
4 192.20 48048858.02
8 389.46 48683010.22
16 767.81 47988126.30
32 1527.34 47729482.30
64 2139.12 33423707.44
128 4010.11 31328973.47
256 7749.86 30272897.24
512 13507.57 26381964.28
1024 15918.48 15545388.20
2048 19846.84 9690838.02
4096 21718.65 5302404.21
8192 146607.66 17896442.75
16384 183905.06 11224674.34
32768 240191.47 7330061.88
65536 280938.91 4286787.57
131072 238150.74 1816945.97
262144 156911.43 598569.60
524288 156919.72 299300.61
1048576 143541.91 136892.24
2097152 28835.20 13749.69
4194304 26170.38 6239.50
Как напомнил мне один комментарий, микробенчмарки OSU неоднократно использовали один и тот же буфер для отправки. Таким образом, данные были в основном в кеше. На этот раз я использовал Intel MPI Benchmarks, у которого есть возможность отправлять данные вне кэша. Я запускал его на одной машине с
srun -n 32 -c 2 -m block:block --cpu_bind=cores, подробный./IMB-MPI1 Uniband -off_cache 40,64
и получил эти цифры, которые, как и ожидалось, упали ниже пропускной способности памяти.
#---------------------------------------------------
# Benchmarking Uniband
# #processes = 32
#---------------------------------------------------
#bytes #repetitions Mbytes/sec Msg/sec
0 1000 0.00 56794458
1 1000 49.89 49892748
2 1000 99.96 49980418
4 1000 199.34 49834857
8 1000 399.30 49912461
16 1000 803.53 50220613
32 1000 1598.35 49948450
64 1000 2212.19 34565472
128 1000 4135.43 32308048
256 1000 7715.76 30139698
512 1000 12773.43 24948113
1024 1000 16440.25 16054932
2048 1000 19674.01 9606451
4096 1000 21574.97 5267326
8192 1000 92699.99 11315916
16384 1000 90449.54 5520602
32768 1000 27340.68 834371
65536 640 25626.04 391022
131072 320 25848.76 197210
262144 160 25939.50 98951
524288 80 25939.48 49476
1048576 40 25909.70 24709
2097152 20 25915.54 12357
4194304 10 25949.97 6187