分布式张量矩阵乘法:重叠通信计算耗时超单操作2.1倍原因排查
问题:分布式张量-矩阵乘法通信计算重叠耗时异常的排查方向
背景信息
我基于坎农算法实现了分布式内存下的张量-矩阵乘法,为隐藏通信延迟采用了通信与计算重叠的方案,但微基准测试结果不符合预期:
- 仅通信耗时:521639微秒
- 仅计算耗时:340435微秒
- 重叠操作总耗时:1111500微秒(是最长单操作的2.1倍)
- 通信+计算顺序执行总耗时:1564400微秒
核心代码片段
重叠逻辑的OpenMP+MPI代码
// ... #define COMM_THREAD 0 // ... #pragma omp parallel { if (omp_get_thread_num() == COMM_THREAD) { // perform the comms. auto requests = std::array<MPI_Request, 4>{}; const auto r1 = MPI_Irecv(tens_recv_buffer_->data(), 2 * tens_recv_buffer_->size(), MPI_DOUBLE, src_proc_id_tens_, 2, MPI_COMM_WORLD, &requests[0]); const auto s1 = MPI_Isend(tens_send_buffer_->data(), 2 * tens_send_buffer_->size(), MPI_DOUBLE, target_proc_id_tens_, 2, MPI_COMM_WORLD, &requests[1]); const auto r2 = MPI_Irecv(mat_recv_buffer_->data(), 2 * mat_recv_buffer_->size(), MPI_DOUBLE, src_proc_id_mat_, 3, MPI_COMM_WORLD, &requests[2]); const auto s2 = MPI_Isend(mat_send_buffer_->data(), 2 * mat_send_buffer_->size(), MPI_DOUBLE, target_proc_id_mat_, 3, MPI_COMM_WORLD, &requests[3]); if (MPI_SUCCESS != s1 || MPI_SUCCESS != r1 || MPI_SUCCESS != s2 || MPI_SUCCESS != r2) { throw std::runtime_error("tensor_matrix_mult_mpi_sendrecv_error"); } if (MPI_SUCCESS != MPI_Waitall(requests.size(), requests.data(), MPI_STATUSES_IGNORE)) { throw std::runtime_error("tensor_matrix_mult_mpi_waitall_error"); } } else { const auto work_indices = schedule_thread_work(tens_recv_buffer_->get_n1(), 1); shared_mem::tensor_matrix_mult(*tens_send_buffer_, *mat_send_buffer_, *result_, work_indices); } }
MPI线程初始化代码
auto provided_thread_support = int{-1}; MPI_Init_thread(&argc, &argv, MPI_THREAD_FUNNELED, &provided_thread_support); if (provided_thread_support < MPI_THREAD_FUNNELED) { std::cerr << "Fatal error: Multi-threading support not available with the current MPI implementation." << std::endl; MPI_Abort(MPI_COMM_WORLD, MPI_ERR_UNKNOWN); }
关键前提
- 通信线程与计算线程对
tens_send_buffer和mat_send_buffer_均为只读访问 - 已使用独立缓冲区测试,问题复现
- 环境:Intel OneAPI v2021.6.0 MPI,2颗Intel Xeon Platinum 8168(48核,无SMT,线程绑核),数据已映射至对应内存节点,大小为600³的张量及小尺寸张量均存在该问题
可能的排查方向与原因推测
- MPI线程模型限制:当前使用
MPI_THREAD_FUNNELED模型,要求所有MPI调用必须由主线程发起。通信线程(线程0)执行MPI异步操作时,若被计算线程抢占CPU资源,MPI库依赖主线程推进的后台通信逻辑会被阻塞,导致通信延迟大幅增加。 - 内存带宽竞争:通信线程的MPI读写操作与计算线程的密集内存访问共享同一NUMA节点带宽,即使是只读访问,大量缓存miss和总线争用会同时拖慢通信与计算速度,叠加后总耗时远超单独执行的最大值。
- OpenMP调度与绑核问题:若COMM_THREAD与计算线程绑定到同一NUMA节点,或绑核脚本未正确隔离核心,会引发核心资源竞争;OpenMP默认调度可能抢占线程0的执行时间片,导致MPI
Waitall等待过程中通信实际完成被延迟。 - MPI异步操作退化:Intel MPI的
MPI_Isend在特定场景下(如对方未启动接收、缓冲区过小)可能退化为同步发送,导致通信线程被阻塞,无法真正实现重叠,反而增加线程调度开销。 - 计算任务负载不均:
schedule_thread_work的任务划分若存在失衡,部分计算线程空闲会加剧内存带宽竞争,降低核心资源利用效率,间接影响通信线程执行。 - 线程同步额外开销:OpenMP并行区的创建、销毁及隐式线程同步会引入额外开销,重叠操作时这些开销叠加在通信与计算耗时上,推高总耗时。
内容的提问来源于stack exchange,提问作者Nitin Malapally
相关产品推荐
相关产品推荐

