进程vm readv在MPI中经过一定数量的iovec后失败

进程vm readv在MPI中经过一定数量的iovec后失败,mpi,openmpi,dma,Mpi,Openmpi,Dma,我使用process\u vm\u readv在MPI中从一个进程到另一个进程获取数据。 我发现程序将在给定一定数量的iovec(在本例中为1024)以处理\u vm\u readv之后开始获取垃圾。 我不确定发生了什么,内核是否内存不足?或者我的代码有问题。 或者进程\u vm\u readv是否有iovec的上限? 我为iovec自行生成了一个向量模式(每16个字节中有8个字节)。 程序将一直运行,直到两个线程上的1GB都充满了此模式。 sbuf和rbuf已分别分配1GB内存。 并且该程序位

我使用process\u vm\u readv在MPI中从一个进程到另一个进程获取数据。
我发现程序将在给定一定数量的iovec(在本例中为1024)以处理\u vm\u readv之后开始获取垃圾。
我不确定发生了什么,内核是否内存不足?或者我的代码有问题。
或者进程\u vm\u 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);

}
void do_测试(int slen,int rlen,int scont,int rcount,void*sbuf,void*rbuf){
int秩,err;
双定时器;
MPI_Win Win;
pid_t pid;
MPI通信等级(MPI通信世界和等级);
如果(秩==0){
MPI\u Win\u create(NULL、0、1、MPI\u INFO\u NULL、MPI\u COMM\u WORLD和Win);
int send_iovcnt;
结构iovec*发送iov;
结构iovec*iov=malloc(sizeof(结构iovec)*scont);
for(int p=0;p
在中找到的是以下文本:

liovcnt
riovcnt
参数中指定的值必须小于或等于
IOV\u MAX
(在
中定义,或可通过调用
sysconf(\u SC\u IOV\u MAX)
访问)

在我的Linux系统上,
IOV_MAX
(最终定义在
/usr/include/x86_64-Linux-gnu/bits/uio_lim.h
)的值为1024。

在中找到的是以下文本:

liovcnt
riovcnt
参数中指定的值必须小于或等于
IOV\u MAX
(在
中定义,或可通过调用
sysconf(\u SC\u IOV\u MAX)
访问)


在我的Linux系统上,
IOV_MAX
(最终定义在
/usr/include/x86_64-Linux-gnu/bits/uio_lim.h
中)是1024。

出于好奇,为什么要将MPI等可移植API与Linux特定系统调用混合使用?MPI提供了自己的一组可移植调用,允许一个列组直接访问另一个列组的内存。如果需要在同一节点上的列组之间快速交换信息,只需公开共享内存窗口即可_Win_allocate_shared消除了这种需要。这只是出于好奇,为什么要将MPI等可移植API与Linux特定系统调用混合使用?MPI提供了自己的一组可移植调用,允许一个列组直接访问另一列组的内存。如果需要在同一列组上的列组之间快速交换信息节点,只需公开共享内存窗口。完全正确。MPI_Win_allocate_shared无需这样做。它只是一个实验。有没有办法将它设置为IOV_MAX到其他值?没有。该值在
include/uapi/Linux/uio.h
中的Linux内核源代码中进行硬编码。理论上,您可以用更高的值构建自己的内核,但是这只适用于您,目前还不清楚哪些假设会被打破。有没有办法将其设置为IOV_MAX,并将其设置为其他值?没有。该值在
include/uapi/Linux/uio.h
中的Linux内核源代码中进行了硬编码。从理论上讲,您可能能够构建具有更高值的内核,但这只适用于您,而不是什么样的假设会被打破。