我尝试在与10GE连接的两台机器之间进行数据交换。数据大小足够大(8 GB),以期望网络利用率接近最大值。但令人惊讶的是我发现了完全不同的行为
为了检查吞吐量,我使用了两个不同的程序 - nethogs
和nload
,这两个程序都显示网络利用率远低于预期。此外,结果是不可预测的 - 有时同时使用输入和输出信道,但有时发送和接收被分开,好像存在半双工信道。 nload
的示例输出:
Device enp1s0f0 [192.168.0.11] (1/1):
======================================================================================================================
Incoming:
|||||||||||||||||||
.###################
####################|
##################### Curr: 0.00 GBit/s
##################### Avg: 2.08 GBit/s
.##################### Min: 0.00 GBit/s
####################### Max: 6.32 GBit/s
####################### Ttl: 57535.38 GByte
Outgoing:
||||||||||||||||||
##################
|##################
###################|
#################### Curr: 0.00 GBit/s
#################### Avg: 2.09 GBit/s
.#################### Min: 0.00 GBit/s
#####################. Max: 6.74 GBit/s
###################### Ttl: 57934.64 GByte
我使用的代码在这里:
int main(int argc, char** argv) {
boost::mpi::environment env{};
boost::mpi::communicator world{};
boost::mpi::request reqs[2];
int k = 10;
if(argc > 1)
k = std::atoi(argv[1]);
uint64_t n = (1ul << k);
std::vector<std::complex<double>> sv(n, world.rank());
std::vector<std::complex<double>> rv(n);
int dest = world.rank() == 0 ? 1 : 0;
int src = dest;
world.barrier();
reqs[0] = world.irecv(src, 0, rv.data(), n);
reqs[1] = world.isend(dest, 0, sv.data(), n);
boost::mpi::wait_all(reqs, reqs + 2);
return 0;
}
这是我用来在集群上运行的命令:
mpirun --mca btl_tcp_if_include 192.168.0.0/24 --hostfile ./host_file -n 2 --bind-to core /path/to/shared/folder/mpi_exp 29
29
这意味着将发送2 ^(29 + 4)= 8 GBytes
我做了什么:
通过netcat
成功使频道饱和,证明没有硬件问题。
检查tcpdump
通信期间TCP数据包的大小是不稳定的,很少达到最大值(netcat
情况下稳定)。
检查strace
套接字操作是否正确。
在sysctl
中检查了TCP参数 - 它们没问题。
您能告诉我为什么OpenMPI无法按预期工作吗?
编辑(14.08.2018):
最后我能够继续深入研究这个问题。下面是OSU带宽基准测试的输出(它没有任何mca选项运行):
# OSU MPI Bandwidth Test v5.3
# Size Bandwidth (MB/s)
1 0.50
2 0.98
4 1.91
8 3.82
16 6.92
32 10.32
64 22.03
128 43.95
256 94.74
512 163.96
1024 264.90
2048 400.01
4096 533.47
8192 640.02
16384 705.02
32768 632.03
65536 667.29
131072 842.00
262144 743.82
524288 654.09
1048576 775.50
2097152 759.44
4194304 774.81
实际上我认为这种糟糕的性能是由CPU限制引起的。默认情况下,每个MPI进程都是单线程的,并且它无法使10GE通道饱和。
我知道在构建OpenMPI时通过启用多线程可以与多个线程进行通信。但是这种方法会导致应用程序级别的复杂性增加。
那么是否有可能在负责点对点数据传输的级别内部在OpenMPI中进行多线程发送/接收?