Add support for faster small messages. While sending a message, we check if
the data was buffered by the MX library. If it's the case then we declare the send as completed and disable the completion event for the mx request. This commit was SVN r12935.
Этот коммит содержится в:
родитель
f5b14ff302
Коммит
3eeecc3838
@ -41,6 +41,26 @@ AC_DEFUN([_OMPI_CHECK_MX_UNEXP_HANDLER],[
|
|||||||
unset mx_provide_unexp_handler
|
unset mx_provide_unexp_handler
|
||||||
])
|
])
|
||||||
|
|
||||||
|
AC_DEFUN([_OMPI_CHECK_MX_FORGET],[
|
||||||
|
#
|
||||||
|
# Check if the MX library provide the mx_forget function.
|
||||||
|
#
|
||||||
|
AC_MSG_CHECKING([for a MX version with mx_forget])
|
||||||
|
AC_TRY_LINK([#include <mx_extensions.h>],
|
||||||
|
[mx_forget(0, 0);],
|
||||||
|
[mx_provide_forget="yes"],
|
||||||
|
[mx_provide_forget="no"])
|
||||||
|
AC_MSG_RESULT([$mx_provide_forget])
|
||||||
|
AS_IF([test x"$mx_provide_forget" = "xyes"],
|
||||||
|
[mx_provide_forget=1
|
||||||
|
$2],
|
||||||
|
[mx_provide_forget=0
|
||||||
|
$3])
|
||||||
|
AC_DEFINE_UNQUOTED([MX_HAVE_FORGET], [$mx_provide_forget],
|
||||||
|
[MX allow to forget the completion event for mx_requests])
|
||||||
|
unset mx_provide_forget
|
||||||
|
])
|
||||||
|
|
||||||
AC_DEFUN([_OMPI_CHECK_MX_CONFIG],[
|
AC_DEFUN([_OMPI_CHECK_MX_CONFIG],[
|
||||||
#
|
#
|
||||||
# See if we have MX_API. OpenMPI require a MX version bigger than
|
# See if we have MX_API. OpenMPI require a MX version bigger than
|
||||||
@ -110,6 +130,9 @@ AC_DEFUN([OMPI_CHECK_MX],[
|
|||||||
[ompi_check_mx_happy="no"])])
|
[ompi_check_mx_happy="no"])])
|
||||||
AS_IF([test "$ompi_check_mx_happy" = "yes"],
|
AS_IF([test "$ompi_check_mx_happy" = "yes"],
|
||||||
[_OMPI_CHECK_MX_UNEXP_HANDLER($1, [ompi_check_mx_register="yes"],
|
[_OMPI_CHECK_MX_UNEXP_HANDLER($1, [ompi_check_mx_register="yes"],
|
||||||
|
[ompi_check_mx_register="no"])])
|
||||||
|
AS_IF([test "$ompi_check_mx_happy" = "yes"],
|
||||||
|
[_OMPI_CHECK_MX_FORGET($1, [ompi_check_mx_register="yes"],
|
||||||
[ompi_check_mx_register="no"])])
|
[ompi_check_mx_register="no"])])
|
||||||
|
|
||||||
CPPFLAGS="$ompi_check_mx_$1_save_CPPFLAGS"
|
CPPFLAGS="$ompi_check_mx_$1_save_CPPFLAGS"
|
||||||
|
@ -26,6 +26,8 @@
|
|||||||
#include "ompi/datatype/convertor.h"
|
#include "ompi/datatype/convertor.h"
|
||||||
#include "opal/prefetch.h"
|
#include "opal/prefetch.h"
|
||||||
|
|
||||||
|
#include "mx_extensions.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@ -247,12 +249,7 @@ mca_btl_mx_prepare_src( struct mca_btl_base_module_t* btl,
|
|||||||
if( OPAL_UNLIKELY(NULL == frag) ) {
|
if( OPAL_UNLIKELY(NULL == frag) ) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
#if 1
|
|
||||||
frag->base.des_src_cnt = 2;
|
frag->base.des_src_cnt = 2;
|
||||||
#else
|
|
||||||
frag->base.des_src_cnt = 1;
|
|
||||||
iov.iov_base = (void*)((unsigned char*)frag->segment[0].seg_addr.pval + reserve);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
MCA_BTL_MX_FRAG_ALLOC_EAGER( mx_btl, frag, rc );
|
MCA_BTL_MX_FRAG_ALLOC_EAGER( mx_btl, frag, rc );
|
||||||
@ -262,17 +259,17 @@ mca_btl_mx_prepare_src( struct mca_btl_base_module_t* btl,
|
|||||||
frag->base.des_src_cnt = 1;
|
frag->base.des_src_cnt = 1;
|
||||||
iov.iov_base = (void*)((unsigned char*)frag->segment[0].seg_addr.pval + reserve);
|
iov.iov_base = (void*)((unsigned char*)frag->segment[0].seg_addr.pval + reserve);
|
||||||
}
|
}
|
||||||
frag->segment[0].seg_len = reserve;
|
|
||||||
|
|
||||||
iov.iov_len = max_data;
|
iov.iov_len = max_data;
|
||||||
(void)ompi_convertor_pack(convertor, &iov, &iov_count, &max_data );
|
(void)ompi_convertor_pack(convertor, &iov, &iov_count, &max_data );
|
||||||
*size = max_data;
|
*size = max_data;
|
||||||
|
|
||||||
if( 1 == frag->base.des_src_cnt ) {
|
if( 1 == frag->base.des_src_cnt ) {
|
||||||
frag->segment[0].seg_len += max_data;
|
frag->segment[0].seg_len = reserve + max_data;
|
||||||
if( 0 == reserve )
|
if( 0 == reserve )
|
||||||
frag->segment[0].seg_addr.pval = iov.iov_base;
|
frag->segment[0].seg_addr.pval = iov.iov_base;
|
||||||
} else {
|
} else {
|
||||||
|
frag->segment[0].seg_len = reserve;
|
||||||
frag->segment[1].seg_len = max_data;
|
frag->segment[1].seg_len = max_data;
|
||||||
frag->segment[1].seg_addr.pval = iov.iov_base;
|
frag->segment[1].seg_addr.pval = iov.iov_base;
|
||||||
}
|
}
|
||||||
@ -308,7 +305,7 @@ mca_btl_base_descriptor_t* mca_btl_mx_prepare_dst( struct mca_btl_base_module_t*
|
|||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
MCA_BTL_MX_FRAG_ALLOC_USER(btl, frag, rc);
|
MCA_BTL_MX_FRAG_ALLOC_USER(btl, frag, rc);
|
||||||
if(NULL == frag) {
|
if( OPAL_UNLIKELY(NULL == frag) ) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -320,7 +317,7 @@ mca_btl_base_descriptor_t* mca_btl_mx_prepare_dst( struct mca_btl_base_module_t*
|
|||||||
mx_segment.segment_length = frag->segment[0].seg_len;
|
mx_segment.segment_length = frag->segment[0].seg_len;
|
||||||
mx_return = mx_irecv( mx_btl->mx_endpoint, &mx_segment, 1, frag->segment[0].seg_key.key64,
|
mx_return = mx_irecv( mx_btl->mx_endpoint, &mx_segment, 1, frag->segment[0].seg_key.key64,
|
||||||
BTL_MX_PUT_MASK, NULL, &(frag->mx_request) );
|
BTL_MX_PUT_MASK, NULL, &(frag->mx_request) );
|
||||||
if( MX_SUCCESS != mx_return ) {
|
if( OPAL_UNLIKELY(MX_SUCCESS != mx_return) ) {
|
||||||
opal_output( 0, "Fail to re-register a fragment with the MX NIC ...\n" );
|
opal_output( 0, "Fail to re-register a fragment with the MX NIC ...\n" );
|
||||||
MCA_BTL_MX_FRAG_RETURN( btl, frag );
|
MCA_BTL_MX_FRAG_RETURN( btl, frag );
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -352,7 +349,7 @@ static int mca_btl_mx_put( struct mca_btl_base_module_t* btl,
|
|||||||
mx_segment_t mx_segment[2];
|
mx_segment_t mx_segment[2];
|
||||||
mx_return_t mx_return;
|
mx_return_t mx_return;
|
||||||
|
|
||||||
if( MCA_BTL_MX_CONNECTED != ((mca_btl_mx_endpoint_t*)endpoint)->status ) {
|
if( OPAL_UNLIKELY(MCA_BTL_MX_CONNECTED != ((mca_btl_mx_endpoint_t*)endpoint)->status) ) {
|
||||||
if( MCA_BTL_MX_NOT_REACHEABLE == ((mca_btl_mx_endpoint_t*)endpoint)->status )
|
if( MCA_BTL_MX_NOT_REACHEABLE == ((mca_btl_mx_endpoint_t*)endpoint)->status )
|
||||||
return OMPI_ERROR;
|
return OMPI_ERROR;
|
||||||
if( MCA_BTL_MX_CONNECTION_PENDING == ((mca_btl_mx_endpoint_t*)endpoint)->status )
|
if( MCA_BTL_MX_CONNECTION_PENDING == ((mca_btl_mx_endpoint_t*)endpoint)->status )
|
||||||
@ -374,7 +371,7 @@ static int mca_btl_mx_put( struct mca_btl_base_module_t* btl,
|
|||||||
mx_return = mx_isend( mx_btl->mx_endpoint, mx_segment, descriptor->des_src_cnt,
|
mx_return = mx_isend( mx_btl->mx_endpoint, mx_segment, descriptor->des_src_cnt,
|
||||||
endpoint->mx_peer_addr,
|
endpoint->mx_peer_addr,
|
||||||
descriptor->des_dst[0].seg_key.key64, frag, &frag->mx_request );
|
descriptor->des_dst[0].seg_key.key64, frag, &frag->mx_request );
|
||||||
if( MX_SUCCESS != mx_return ) {
|
if( OPAL_UNLIKELY(MX_SUCCESS != mx_return) ) {
|
||||||
opal_output( 0, "mx_isend fails with error %s\n", mx_strerror(mx_return) );
|
opal_output( 0, "mx_isend fails with error %s\n", mx_strerror(mx_return) );
|
||||||
return OMPI_ERROR;
|
return OMPI_ERROR;
|
||||||
}
|
}
|
||||||
@ -403,7 +400,7 @@ int mca_btl_mx_send( struct mca_btl_base_module_t* btl,
|
|||||||
mx_return_t mx_return;
|
mx_return_t mx_return;
|
||||||
uint64_t total_length;
|
uint64_t total_length;
|
||||||
|
|
||||||
if( MCA_BTL_MX_CONNECTED != ((mca_btl_mx_endpoint_t*)endpoint)->status ) {
|
if( OPAL_UNLIKELY(MCA_BTL_MX_CONNECTED != ((mca_btl_mx_endpoint_t*)endpoint)->status) ) {
|
||||||
if( MCA_BTL_MX_NOT_REACHEABLE == ((mca_btl_mx_endpoint_t*)endpoint)->status )
|
if( MCA_BTL_MX_NOT_REACHEABLE == ((mca_btl_mx_endpoint_t*)endpoint)->status )
|
||||||
return OMPI_ERROR;
|
return OMPI_ERROR;
|
||||||
if( MCA_BTL_MX_CONNECTION_PENDING == ((mca_btl_mx_endpoint_t*)endpoint)->status )
|
if( MCA_BTL_MX_CONNECTION_PENDING == ((mca_btl_mx_endpoint_t*)endpoint)->status )
|
||||||
@ -429,18 +426,41 @@ int mca_btl_mx_send( struct mca_btl_base_module_t* btl,
|
|||||||
opal_output( 0, "mx_isend fails with error %s\n", mx_strerror(mx_return) );
|
opal_output( 0, "mx_isend fails with error %s\n", mx_strerror(mx_return) );
|
||||||
return OMPI_ERROR;
|
return OMPI_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if MX_HAVE_FORGET
|
||||||
|
{
|
||||||
|
uint32_t mx_result;
|
||||||
|
mx_return = mx_ibuffered( mx_btl->mx_endpoint, &(frag->mx_request), &mx_result );
|
||||||
|
if( OPAL_UNLIKELY(MX_SUCCESS != mx_return) ) {
|
||||||
|
opal_output( 0, "mx_ibuffered failed with error %d (%s)\n",
|
||||||
|
mx_return, mx_strerror(mx_return) );
|
||||||
|
return OMPI_ERROR;
|
||||||
|
}
|
||||||
|
if( mx_result ) {
|
||||||
|
mx_return = mx_forget( mx_btl->mx_endpoint, &(frag->mx_request) );
|
||||||
|
frag->base.des_cbfunc( &(mx_btl->super), frag->endpoint, &(frag->base), OMPI_SUCCESS);
|
||||||
|
if( OPAL_UNLIKELY(MX_SUCCESS != mx_return) ) {
|
||||||
|
opal_output( 0, "mx_forget failed with error %d (%s)\n",
|
||||||
|
mx_return, mx_strerror(mx_return) );
|
||||||
|
return OMPI_ERROR;
|
||||||
|
}
|
||||||
|
return OMPI_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
if( 4096 > total_length ) {
|
if( 4096 > total_length ) {
|
||||||
mx_status_t mx_status;
|
mx_status_t mx_status;
|
||||||
uint32_t mx_result;
|
uint32_t mx_result;
|
||||||
|
|
||||||
/* let's check for completness */
|
/* let's check for completness */
|
||||||
mx_return = mx_test( mx_btl->mx_endpoint, &(frag->mx_request), &mx_status, &mx_result );
|
mx_return = mx_test( mx_btl->mx_endpoint, &(frag->mx_request), &mx_status, &mx_result );
|
||||||
if( MX_SUCCESS != mx_return )
|
if( OPAL_UNLIKELY(MX_SUCCESS != mx_return) )
|
||||||
return OMPI_SUCCESS;
|
return OMPI_SUCCESS;
|
||||||
/* call the completion callback */
|
/* call the completion callback */
|
||||||
if( mx_result )
|
if( mx_result )
|
||||||
frag->base.des_cbfunc( &(mx_btl->super), frag->endpoint, &(frag->base), OMPI_SUCCESS);
|
frag->base.des_cbfunc( &(mx_btl->super), frag->endpoint, &(frag->base), OMPI_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
return OMPI_SUCCESS;
|
return OMPI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Загрузка…
Ссылка в новой задаче
Block a user