在 MPI 中进行一定数量的 iovec 后,进程 vm readv 失败
process vm readv fails after certain number of iovec in MPI
我正在使用 process_vm_readv 在 MPI 中将数据从一个进程获取到另一个进程。
我发现程序将在给予 process_vm_readv.
一定数量的 iovec(在本例中为 1024)后开始变得垃圾
我不确定发生了什么,内核 运行 是否内存不足?或者我的代码有问题。
还是 process_vm_readv iovec 有上限?
我为 iovec 自行生成了一个矢量模式(每 16 个字节中有 8 个字节)。
并且程序将 运行 直到 1GB 在两个线程上都被这种模式填充。
sbuf 和 rbuf 已分别分配 1GB 内存。
该程序位于 24GB 以上的机器上。
void do_test( int slen, int rlen, int scount, int rcount, void *sbuf, void *rbuf ){
int rank, err;
double timers[REP];
MPI_Win win;
pid_t pid;
MPI_Comm_rank( MPI_COMM_WORLD, &rank );
if( rank == 0 ){
MPI_Win_create( NULL, 0, 1, MPI_INFO_NULL, MPI_COMM_WORLD, &win );
int send_iovcnt;
struct iovec *send_iov;
struct iovec *iov = malloc( sizeof(struct iovec) * scount );
for( int p = 0; p < scount; p++ ){
iov[p].iov_base = (char*)rbuf + p * 16;
iov[p].iov_len = 8;
}
MPI_Recv( &pid, sizeof(pid_t), MPI_BYTE, 1, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE );
MPI_Recv( &send_iovcnt, 1, MPI_INT, 1, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE );
send_iov = malloc( sizeof(struct iovec) * send_iovcnt );
MPI_Recv( send_iov, sizeof(struct iovec) * send_iovcnt, MPI_BYTE, 1, 2, MPI_COMM_WORLD, MPI_STATUS_IGNORE );
for( int i = 0; i < REP; i++ ){
cache_flush();
timers[i] = MPI_Wtime();
MPI_Win_fence( 0, win );
process_vm_readv( pid, iov, send_iovcnt, send_iov, send_iovcnt, 0 );
MPI_Win_fence( 0, win );
cache_flush();
timers[i] = MPI_Wtime() - timers[i];
}
free(send_iov);
free(iov);
print_result( 8 * scount, REP, timers );
} else if( rank == 1 ){
MPI_Win_create( sbuf, slen, 1, MPI_INFO_NULL, MPI_COMM_WORLD, &win );
struct iovec *iov = malloc( sizeof(struct iovec) * rcount );
for( int p = 0; p < rcount; p++ ){
iov[p].iov_base = (char*)sbuf + p * 16;
iov[p].iov_base = 8;
}
pid = getpid();
MPI_Send( &pid, sizeof(pid_t), MPI_BYTE, 0, 0, MPI_COMM_WORLD );
MPI_Send( &rcount, 1, MPI_INT, 0, 1, MPI_COMM_WORLD );
MPI_Send( iov, rcount * sizeof(struct iovec), MPI_BYTE, 0, 2, MPI_COMM_WORLD );
for( int i = 0; i < REP; i++ ){
cache_flush();
MPI_Win_fence( 0, win );
MPI_Win_fence( 0, win );
}
free(iov);
}
在man page of process_vm_readv(2)
中找到如下文字:
The values specified in the liovcnt
and riovcnt
arguments must be less than or equal to IOV_MAX
(defined in <limits.h>
or accessible via the call sysconf(_SC_IOV_MAX)
).
在我的Linux系统上,IOV_MAX
的值(最终在/usr/include/x86_64-linux-gnu/bits/uio_lim.h
中定义)是1024。
我正在使用 process_vm_readv 在 MPI 中将数据从一个进程获取到另一个进程。
我发现程序将在给予 process_vm_readv.
一定数量的 iovec(在本例中为 1024)后开始变得垃圾
我不确定发生了什么,内核 运行 是否内存不足?或者我的代码有问题。
还是 process_vm_readv iovec 有上限?
我为 iovec 自行生成了一个矢量模式(每 16 个字节中有 8 个字节)。
并且程序将 运行 直到 1GB 在两个线程上都被这种模式填充。
sbuf 和 rbuf 已分别分配 1GB 内存。
该程序位于 24GB 以上的机器上。
void do_test( int slen, int rlen, int scount, int rcount, void *sbuf, void *rbuf ){
int rank, err;
double timers[REP];
MPI_Win win;
pid_t pid;
MPI_Comm_rank( MPI_COMM_WORLD, &rank );
if( rank == 0 ){
MPI_Win_create( NULL, 0, 1, MPI_INFO_NULL, MPI_COMM_WORLD, &win );
int send_iovcnt;
struct iovec *send_iov;
struct iovec *iov = malloc( sizeof(struct iovec) * scount );
for( int p = 0; p < scount; p++ ){
iov[p].iov_base = (char*)rbuf + p * 16;
iov[p].iov_len = 8;
}
MPI_Recv( &pid, sizeof(pid_t), MPI_BYTE, 1, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE );
MPI_Recv( &send_iovcnt, 1, MPI_INT, 1, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE );
send_iov = malloc( sizeof(struct iovec) * send_iovcnt );
MPI_Recv( send_iov, sizeof(struct iovec) * send_iovcnt, MPI_BYTE, 1, 2, MPI_COMM_WORLD, MPI_STATUS_IGNORE );
for( int i = 0; i < REP; i++ ){
cache_flush();
timers[i] = MPI_Wtime();
MPI_Win_fence( 0, win );
process_vm_readv( pid, iov, send_iovcnt, send_iov, send_iovcnt, 0 );
MPI_Win_fence( 0, win );
cache_flush();
timers[i] = MPI_Wtime() - timers[i];
}
free(send_iov);
free(iov);
print_result( 8 * scount, REP, timers );
} else if( rank == 1 ){
MPI_Win_create( sbuf, slen, 1, MPI_INFO_NULL, MPI_COMM_WORLD, &win );
struct iovec *iov = malloc( sizeof(struct iovec) * rcount );
for( int p = 0; p < rcount; p++ ){
iov[p].iov_base = (char*)sbuf + p * 16;
iov[p].iov_base = 8;
}
pid = getpid();
MPI_Send( &pid, sizeof(pid_t), MPI_BYTE, 0, 0, MPI_COMM_WORLD );
MPI_Send( &rcount, 1, MPI_INT, 0, 1, MPI_COMM_WORLD );
MPI_Send( iov, rcount * sizeof(struct iovec), MPI_BYTE, 0, 2, MPI_COMM_WORLD );
for( int i = 0; i < REP; i++ ){
cache_flush();
MPI_Win_fence( 0, win );
MPI_Win_fence( 0, win );
}
free(iov);
}
在man page of process_vm_readv(2)
中找到如下文字:
The values specified in the
liovcnt
andriovcnt
arguments must be less than or equal toIOV_MAX
(defined in<limits.h>
or accessible via the callsysconf(_SC_IOV_MAX)
).
在我的Linux系统上,IOV_MAX
的值(最终在/usr/include/x86_64-linux-gnu/bits/uio_lim.h
中定义)是1024。