⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mpidtime.c

📁 mpi并行计算的c++代码 可用vc或gcc编译通过 可以用来搭建并行计算试验环境
💻 C
字号:
/* -*- Mode: C; c-basic-offset:4 ; -*- *//*  $Id: mpidtime.c,v 1.35 2005/07/07 18:07:40 ashton Exp $ * *  (C) 2001 by Argonne National Laboratory. *      See COPYRIGHT in top-level directory. */#include "mpiimpl.h"#if MPICH_TIMER_KIND == USE_GETHRTIME /*  * MPID_Time_t is hrtime_t, which under Solaris is defined as a 64bit * longlong_t .  However, the Solaris header files will define * longlong_t as a structure in some circumstances, making arithmetic * with hrtime_t invalid.  FIXME.   * To fix this, we'll need to test hrtime_t arithmetic in the configure * program, and if it fails, check for the Solaris defintions ( * union { double _d; int32_t _l[2]; }.  Alternately, we may decide that * if hrtime_t is not supported, then neither is gethrtime. * * Note that the Solaris sys/types.h file *assumes* that no other compiler * supports an 8 byte long long.  We can also cast hrtime_t to long long  * if long long is available and 8 bytes. */void MPID_Wtime( MPID_Time_t *timeval ){    *timeval = gethrtime();}void MPID_Wtime_diff( MPID_Time_t *t1, MPID_Time_t *t2, double *diff ){    *diff = 1.0e-9 * (double)( *t2 - *t1 );}void MPID_Wtime_todouble( MPID_Time_t *t, double *val ){    *val = 1.0e-9 * (*t);}void MPID_Wtime_acc( MPID_Time_t *t1,MPID_Time_t *t2, MPID_Time_t *t3 ){    *t3 += ((*t2) - (*t1));}double MPID_Wtick( void ){    /* According to the documentation, ticks should be in nanoseconds.  This        is untested */     return 1.0e-9;}#elif MPICH_TIMER_KIND == USE_CLOCK_GETTIMEvoid MPID_Wtime( MPID_Time_t *timeval ){    /* POSIX timer (14.2.1, page 311) */    clock_gettime( CLOCK_REALTIME, timeval );}void MPID_Wtime_diff( MPID_Time_t *t1, MPID_Time_t *t2, double *diff ){    *diff = ((double) (t2->tv_sec - t1->tv_sec) + 		1.0e-9 * (double) (t2->tv_nsec - t1->tv_nsec) );}void MPID_Wtime_todouble( MPID_Time_t *t, double *val ){    *val = ((double) t->tv_sec + 1.0e-9 * (double) t->tv_nsec );}void MPID_Wtime_acc( MPID_Time_t *t1, MPID_Time_t *t2, MPID_Time_t *t3 ){    int nsec, sec;        nsec = t1->tv_nsec + t2->tv_nsec;    sec  = t1->tv_sec + t2->tv_sec;    if (nsec > 1.0e9) {	nsec -= 1.0e9;	sec++;    }    t3->tv_sec = sec;    t3->tv_nsec = nsec;}double MPID_Generic_wtick(void);double MPID_Wtick( void ){    struct timespec res;    int rc;    rc = clock_getres( CLOCK_REALTIME, &res );    if (!rc) 	/* May return -1 for unimplemented ! */	return res.tv_sec + 1.0e-9 * res.tv_nsec;    /* Sigh.  If not POSIX not implemented, then we need to use the generic        tick routine */    return MPID_Generic_wtick();}#define MPICH_NEEDS_GENERIC_WTICK/* Rename the function so that we can access it */#define MPID_Wtick MPID_Generic_wtick#elif MPICH_TIMER_KIND == USE_GETTIMEOFDAY#ifdef HAVE_SYS_TIME_H#include <sys/time.h>#endif#ifdef HAVE_UNISTD_H#include <unistd.h>#endifvoid MPID_Wtime( MPID_Time_t *tval ){    gettimeofday(tval,NULL);}void MPID_Wtime_diff( MPID_Time_t *t1, MPID_Time_t *t2, double *diff ){    *diff = ((double) (t2->tv_sec - t1->tv_sec) + 		.000001 * (double) (t2->tv_usec - t1->tv_usec) );}void MPID_Wtime_todouble( MPID_Time_t *t, double *val ){    *val = (double) t->tv_sec + .000001 * (double) t->tv_usec;}void MPID_Wtime_acc( MPID_Time_t *t1, MPID_Time_t *t2, MPID_Time_t *t3 ){    int usec, sec;        usec = t2->tv_usec - t1->tv_usec;    sec  = t2->tv_sec - t1->tv_sec;    t3->tv_usec += usec;    t3->tv_sec += sec;    /* Handle carry to the integer seconds field */    if (t3->tv_usec > 1.0e6) {	t3->tv_usec -= 1.0e6;	t3->tv_sec++;    }}#define MPICH_NEEDS_GENERIC_WTICK#elif MPICH_TIMER_KIND == USE_LINUX86_CYCLE#include <sys/time.h>double g_seconds_per_tick;double MPID_Wtick(void){    return g_seconds_per_tick;}void MPID_Wtime_init(){    unsigned long long t1, t2;    struct timeval tv1, tv2;    double td1, td2;    gettimeofday(&tv1, NULL);    MPID_Wtime(&t1);    usleep(250000);    gettimeofday(&tv2, NULL);    MPID_Wtime(&t2);    td1 = tv1.tv_sec + tv1.tv_usec / 1000000.0;    td2 = tv2.tv_sec + tv2.tv_usec / 1000000.0;    g_seconds_per_tick = (td2 - td1) / (double)(t2 - t1);}/* Time stamps created by a macro */void MPID_Wtime_diff( MPID_Time_t *t1, MPID_Time_t *t2, double *diff ){    *diff = (double)( *t2 - *t1 ) * g_seconds_per_tick;}void MPID_Wtime_todouble( MPID_Time_t *t, double *val ){    /* This returns the number of cycles as the "time".  This isn't correct       for implementing MPI_Wtime, but it does allow us to insert cycle       counters into test programs */    *val = (double)*t * g_seconds_per_tick;}void MPID_Wtime_acc( MPID_Time_t *t1,MPID_Time_t *t2, MPID_Time_t *t3 ){    *t3 += (*t2 - *t1);}#elif MPICH_TIMER_KIND == USE_GCC_IA64_CYCLE#include <sys/time.h>double g_seconds_per_tick;double MPID_Wtick(void){    return g_seconds_per_tick;}void MPID_Wtime_init(){    unsigned long long t1, t2;    struct timeval tv1, tv2;    double td1, td2;    gettimeofday(&tv1, NULL);    MPID_Wtime(&t1);    usleep(250000);    gettimeofday(&tv2, NULL);    MPID_Wtime(&t2);    td1 = tv1.tv_sec + tv1.tv_usec / 1000000.0;    td2 = tv2.tv_sec + tv2.tv_usec / 1000000.0;    g_seconds_per_tick = (td2 - td1) / (double)(t2 - t1);}/* Time stamps created by a macro */void MPID_Wtime_diff( MPID_Time_t *t1, MPID_Time_t *t2, double *diff ){    *diff = (double)( *t2 - *t1 ) * g_seconds_per_tick;}void MPID_Wtime_todouble( MPID_Time_t *t, double *val ){    /* This returns the number of cycles as the "time".  This isn't correct       for implementing MPI_Wtime, but it does allow us to insert cycle       counters into test programs */    *val = (double)*t * g_seconds_per_tick;}void MPID_Wtime_acc( MPID_Time_t *t1,MPID_Time_t *t2, MPID_Time_t *t3 ){    *t3 += (*t2 - *t1);}#elif MPICH_TIMER_KIND == USE_LINUXALPHA_CYCLE/* Code from LinuxJournal #42 (Oct-97), p50;    thanks to Dave Covey dnc@gi.alaska.edu   Untested */#error "LinuxAlpha cycle counter not supported"/*    unsigned long cc;    asm volatile( "rpcc %0" : "=r"(cc) : : "memory" ); */    /* Convert to time.  Scale cc by 1024 incase it would overflow a double;       consider using long double as well */void MPID_Wtime_diff( MPID_Time_t *t1, MPID_Time_t *t2, double *diff )    *diff = 1024.0 * ((double)(cc/1024) / (double)CLOCK_FREQ_HZ);void MPID_Wtime_todouble( MPID_Time_t *t, double *val ){}void MPID_Wtime_acc( MPID_Time_t *t1, MPID_Time_t *t2, MPID_Time_t *t3 ){}double MPID_Wtick( void ) {    return 1.0;}#elif (MPICH_TIMER_KIND == USE_WIN86_CYCLE) || (MPICH_TIMER_KIND == USE_WIN64_CYCLE)double g_seconds_per_tick;double MPID_Wtick(void){    return g_seconds_per_tick;}void MPID_Wtime_todouble( MPID_Time_t *t, double *d){    *d = (double)(__int64)*t * g_seconds_per_tick;}void MPID_Wtime_diff( MPID_Time_t *t1, MPID_Time_t *t2, double *diff){    *diff = (double)((__int64)( *t2 - *t1 )) * g_seconds_per_tick;}void MPID_Wtime_init(){    MPID_Time_t t1, t2;    DWORD s1, s2;    double d;    int i;    MPID_Wtime(&t1);    MPID_Wtime(&t1);    /* time an interval using both timers */    s1 = GetTickCount();    MPID_Wtime(&t1);    /*Sleep(250);*/ /* Sleep causes power saving cpu's to stop which stops the counter */    while (GetTickCount() - s1 < 200)    {	for (i=2; i<1000; i++)	    d = (double)i / (double)(i-1);    }    s2 = GetTickCount();    MPID_Wtime(&t2);    /* calculate the frequency of the assembly cycle counter */    g_seconds_per_tick = ((double)(s2 - s1) / 1000.0) / (double)((__int64)(t2 - t1));    /*    printf("t2-t1 %10d\nsystime diff %d\nfrequency %g\n CPU MHz %g\n", 	(int)(t2-t1), (int)(s2 - s1), g_seconds_per_tick, g_seconds_per_tick * 1.0e6);    */}/*void TIMER_INIT(){    TIMER_TYPE t1, t2;    FILETIME ft1, ft2;    SYSTEMTIME st1, st2;    ULARGE_INTEGER u1, u2;    t1 = 5;    t2 = 5;    GET_TIME(&t1);    GET_TIME(&t1);    //GetSystemTimeAsFileTime(&ft1);    GetSystemTime(&st1);    GET_TIME(&t1);    Sleep(500);    //GetSystemTimeAsFileTime(&ft2);    GetSystemTime(&st2);    GET_TIME(&t2);    SystemTimeToFileTime(&st1, &ft1);    SystemTimeToFileTime(&st2, &ft2);    u1.QuadPart = ft1.dwHighDateTime;    u1.QuadPart = u1.QuadPart << 32;    u1.QuadPart |= ft1.dwLowDateTime;    u2.QuadPart = ft2.dwHighDateTime;    u2.QuadPart = u2.QuadPart << 32;    u2.QuadPart |= ft2.dwLowDateTime;    g_seconds_per_tick = (1e-7 * (double)((__int64)(u2.QuadPart - u1.QuadPart))) / (double)((__int64)(t2 - t1));    printf("t2   %10d\nt1   %10d\ndiff %10d\nsystime diff %d\nfrequency %g\n CPU MHz %g\n", 	(int)t2, (int)t1, (int)(t2-t1), (int)(u2.QuadPart - u1.QuadPart), g_seconds_per_tick, g_seconds_per_tick * 1.0e6);    printf("t2-t1 %10d\nsystime diff %d\nfrequency %g\n CPU MHz %g\n", 	(int)(t2-t1), (int)(u2.QuadPart - u1.QuadPart), g_seconds_per_tick, g_seconds_per_tick * 1.0e6);}*/#elif MPICH_TIMER_KIND == USE_QUERYPERFORMANCECOUNTERdouble g_seconds_per_tick=0.0;  /* High performance counter frequency */void MPID_Wtime_init(void){    LARGE_INTEGER n;    QueryPerformanceFrequency(&n);    g_seconds_per_tick = 1.0 / (double)n.QuadPart;}double MPID_Wtick(void){    return g_seconds_per_tick;}void MPID_Wtime_todouble( MPID_Time_t *t, double *val ){    *val = (double)t->QuadPart * g_seconds_per_tick;}void MPID_Wtime_diff( MPID_Time_t *t1, MPID_Time_t *t2, double *diff ){    LARGE_INTEGER n;    n.QuadPart = t2->QuadPart - t1->QuadPart;    *diff = (double)n.QuadPart * g_seconds_per_tick;}void MPID_Wtime_acc( MPID_Time_t *t1, MPID_Time_t *t2, MPID_Time_t *t3 ){    t3->QuadPart += ((t2->QuadPart) - (t1->QuadPart));}#endif#ifdef MPICH_NEEDS_GENERIC_WTICK/* * For timers that do not have defined resolutions, compute the resolution * by sampling the clock itself. */double MPID_Wtick( void ){    static double tickval = -1.0;    double timediff;    MPID_Time_t t1, t2;    int    cnt;    int    icnt;    if (tickval < 0.0) {	tickval = 1.0e6;	for (icnt=0; icnt<10; icnt++) {	    cnt = 1000;	    MPID_Wtime( &t1 );	    while (cnt--) {		MPID_Wtime( &t2 );		MPID_Wtime_diff( &t1, &t2, &timediff );		if (timediff > 0) break;		}	    if (cnt && timediff > 0.0 && timediff < tickval) {		MPID_Wtime_diff( &t1, &t2, &tickval );	    }	}    }    return tickval;}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -