📄 mm.c
字号:
* three 20x20 matrices reside in cache; two may be enough
*/
void maeno(lparm)
int lparm;
{
int i,j,k,kk,i2 /* ,r */ ,kt,it;
double t0,t1,t2,t3,s,t4,t5,t6,t7;
for(i=0;i<N;i++)
for(j=0;j<N;j++) {
c[i][j]=0.0;
}
for (i2=0; i2<N; i2+=lparm)
for (kk=0; kk<N; kk+=lparm) {
it=i2+lparm;
kt=kk+lparm;
for (j=0; j<N; j+=4)
for(i=i2;i<it;i+=2) {
t0=t1=t2=t3=0.0;
t4=t5=t6=t7=0.0;
for(k=kk; k<kt; k++) {
s=a[i][k];
t0 += s*b[k][j];
t1 += s*b[k][j+1];
t2 += s*b[k][j+2];
t3 += s*b[k][j+3];
s=a[i+1][k];
t4 += s*b[k][j];
t5 += s*b[k][j+1];
t6 += s*b[k][j+2];
t7 += s*b[k][j+3];
}
c[i][j]+=t0;
c[i][j+1]+=t1;
c[i][j+2]+=t2;
c[i][j+3]+=t3;
c[i+1][j]+=t4;
c[i+1][j+1]+=t5;
c[i+1][j+2]+=t6;
c[i+1][j+3]+=t7;
}
}
}
void warner(nb)
int nb;
{
int i,j,k;
int ii,jj,kk;
double s00,s01,s10,s11;
/*
* Matrix Multiply by Dan Warner, Dept. of Mathematics, Clemson University
*
* mmbu2.f multiplies matrices a and b
* a and b are n by n matrices
* nb is the blocking parameter.
* the tuning guide indicates nb = 50 is reasonable for the
* ibm model 530 hence 25 should be reasonable for the 320
* since the 320 has 32k rather than 64k of cache.
* Inner loops unrolled to depth of 2
* The loop functions without clean up code at the end only
* if the unrolling occurs to a depth k which divides into n
* in this case n must be divisible by 2.
* The blocking parameter nb must divide into n if the
* multiply is to succeed without clean up code at the end.
*
* converted to c by Mark Smotherman
* note that nb must also be divisible by 2 => cannot use 25, so use 20
*/
for( ii = 0; ii < N; ii += nb ){
for( jj = 0; jj < N; jj += nb ){
for( i = ii; i < ii + nb ; i++ ){
for( j = jj; j < jj + nb ; j++ ){
c[i][j] = 0.0;
}
}
for( kk = 0; kk < N; kk += nb ){
for( i = ii; i < ii + nb ; i += 2 ){
for( j = jj; j < jj + nb ; j += 2 ){
s00 = c[i ][j ];
s01 = c[i ][j+1];
s10 = c[i+1][j ];
s11 = c[i+1][j+1];
for( k = kk; k < kk + nb ; k++ ){
s00 = s00 + a[i ][k]*b[k][j ];
s01 = s01 + a[i ][k]*b[k][j+1];
s10 = s10 + a[i+1][k]*b[k][j ];
s11 = s11 + a[i+1][k]*b[k][j+1];
}
c[i ][j ] = s00;
c[i ][j+1] = s01;
c[i+1][j ] = s10;
c[i+1][j+1] = s11;
}
}
}
}
}
}
/********************************************/
/* Contributed by Robert Debath 26 Nov 1995 */
/* rdebath@cix.compulink.co.uk */
/********************************************/
void robert(void)
{
int i,j,k;
double temp, *pa, *pb;
for (i = 0;i < N; i++)
{
for (j = 0;j < N; j++)
{
bt[j][i] = b[i][j];
}
}
for (i = 0; i < N; i++)
{
for (j = 0; j < N; j++)
{
pa = &a[i][0];
pb = &bt[j][0];
temp = (*pa++) * (*pb++);
for (k = 1; k < N; k++)
{
temp += (*pa++) * (*pb++);
}
c[i][j] = temp;
}
}
}
/*****************************************************/
/* Various timer routines. */
/* Al Aburto, aburto@marlin.nosc.mil, 16 Dec 1995 */
/* */
/* t = dtime() outputs the current time in seconds. */
/* Use CAUTION as some of these routines will mess */
/* up when timing across the hour mark!!! */
/* */
/* For timing I use the 'user' time whenever */
/* possible. Using 'user+sys' time is a separate */
/* issue. */
/* */
/* Example Usage: */
/* [timer options added here] */
/* main() */
/* { */
/* double starttime,benchtime,dtime(); */
/* */
/* starttime = dtime(); */
/* [routine to time] */
/* benchtime = dtime() - starttime; */
/* } */
/* */
/* [timer code below added here] */
/*****************************************************/
/*********************************/
/* Timer code. */
/*********************************/
/*******************/
/* Amiga dtime() */
/*******************/
#ifdef Amiga
#include <ctype.h>
#define HZ 50
double dtime()
{
double q;
struct tt {
long days;
long minutes;
long ticks;
} tt;
DateStamp(&tt);
q = ((double)(tt.ticks + (tt.minutes * 60L * 50L))) / (double)HZ;
return q;
}
#endif
/*****************************************************/
/* UNIX dtime(). This is the preferred UNIX timer. */
/* Provided by: Markku Kolkka, mk59200@cc.tut.fi */
/* HP-UX Addition by: Bo Thide', bt@irfu.se */
/*****************************************************/
#ifdef UNIX
#include <sys/time.h>
#include <sys/resource.h>
#ifdef __hpux
#include <sys/syscall.h>
#define getrusage(a,b) syscall(SYS_getrusage,a,b)
#endif
struct rusage rusage;
double dtime()
{
double q;
getrusage(RUSAGE_SELF,&rusage);
q = (double)(rusage.ru_utime.tv_sec);
q = q + (double)(rusage.ru_utime.tv_usec) * 1.0e-06;
return q;
}
#endif
/***************************************************/
/* UNIX_Old dtime(). This is the old UNIX timer. */
/* Use only if absolutely necessary as HZ may be */
/* ill defined on your system. */
/***************************************************/
#ifdef UNIX_Old
#include <sys/types.h>
#include <sys/times.h>
#include <sys/param.h>
#ifndef HZ
#define HZ 60
#endif
struct tms tms;
double dtime()
{
double q;
times(&tms);
q = (double)(tms.tms_utime) / (double)HZ;
return q;
}
#endif
/*********************************************************/
/* VMS dtime() for VMS systems. */
/* Provided by: RAMO@uvphys.phys.UVic.CA */
/* Some people have run into problems with this timer. */
/*********************************************************/
#ifdef VMS
#include time
#ifndef HZ
#define HZ 100
#endif
struct tbuffer_t
{
int proc_user_time;
int proc_system_time;
int child_user_time;
int child_system_time;
};
struct tbuffer_t tms;
double dtime()
{
double q;
times(&tms);
q = (double)(tms.proc_user_time) / (double)HZ;
return q;
}
#endif
/*******************************/
/* BORLAND C dtime() for DOS */
/*******************************/
#ifdef BORLAND_C
#include <ctype.h>
#include <dos.h>
#include <time.h>
#define HZ 100
struct time tnow;
double dtime()
{
double q;
gettime(&tnow);
q = 60.0 * (double)(tnow.ti_min);
q = q + (double)(tnow.ti_sec);
q = q + (double)(tnow.ti_hund)/(double)HZ;
return q;
}
#endif
/***************************************/
/* Microsoft C (MSC) dtime() for DOS */
/***************************************/
#ifdef MSC
#include <time.h>
#include <ctype.h>
#define HZ CLOCKS_PER_SEC
clock_t tnow;
double dtime()
{
double q;
tnow = clock();
q = (double)tnow / (double)HZ;
return q;
}
#endif
/**************************************/
/* Macintosh (MAC) Think C dtime() */
/**************************************/
#ifdef MAC
#include <time.h>
#define HZ 60
double dtime()
{
double q;
q = (double)clock() / (double)HZ;
return q;
}
#endif
/************************************************************/
/* iPSC/860 (IPSC) dtime() for i860. */
/* Provided by: Dan Yergeau, yergeau@gloworm.Stanford.EDU */
/************************************************************/
#ifdef IPSC
extern double dclock();
double dtime()
{
double q;
q = dclock();
return q;
}
#endif
/**************************************************/
/* FORTRAN dtime() for Cray type systems. */
/* This is the preferred timer for Cray systems. */
/**************************************************/
#ifdef FORTRAN_SEC
fortran double second();
double dtime()
{
double q;
second(&q);
return q;
}
#endif
/***********************************************************/
/* UNICOS C dtime() for Cray UNICOS systems. Don't use */
/* unless absolutely necessary as returned time includes */
/* 'user+system' time. Provided by: R. Mike Dority, */
/* dority@craysea.cray.com */
/***********************************************************/
#ifdef CTimer
#include <time.h>
double dtime()
{
double q;
clock_t t;
t = clock();
q = (double)t / (double)CLOCKS_PER_SEC;
return q;
}
#endif
/********************************************/
/* Another UNIX timer using gettimeofday(). */
/* However, getrusage() is preferred. */
/********************************************/
#ifdef GTODay
#include <sys/time.h>
struct timeval tnow;
double dtime()
{
double q;
gettimeofday(&tnow,NULL);
q = (double)tnow.tv_sec + (double)tnow.tv_usec * 1.0e-6;
return q;
}
#endif
/*****************************************************/
/* Fujitsu UXP/M timer. */
/* Provided by: Mathew Lim, ANUSF, M.Lim@anu.edu.au */
/*****************************************************/
#ifdef UXPM
#include <sys/types.h>
#include <sys/timesu.h>
struct tmsu rusage;
double dtime()
{
double q;
timesu(&rusage);
q = (double)(rusage.tms_utime) * 1.0e-06;
return q;
}
#endif
/**********************************************/
/* Macintosh (MAC_TMgr) Think C dtime() */
/* requires Think C Language Extensions or */
/* #include <MacHeaders> in the prefix */
/* provided by Francis H Schiffer 3rd (fhs) */
/* skipschiffer@genie.geis.com */
/**********************************************/
#ifdef MAC_TMgr
#include <Timer.h>
#include <stdlib.h>
static TMTask mgrTimer;
static Boolean mgrInited = false;
static double mgrClock;
#define RMV_TIMER RmvTime( (QElemPtr)&mgrTimer )
#define MAX_TIME 1800000000L
/* MAX_TIME limits time between calls to */
/* dtime( ) to no more than 30 minutes */
/* this limitation could be removed by */
/* creating a completion routine to sum */
/* 30 minute segments (fhs 1994 feb 9) */
static void Remove_timer( )
{
RMV_TIMER;
mgrInited = false;
}
double dtime( )
{
if( mgrInited ) {
RMV_TIMER;
mgrClock += (MAX_TIME + mgrTimer.tmCount)*1.0e-6;
} else {
if( _atexit( &Remove_timer ) == 0 ) mgrInited = true;
mgrClock = 0.0;
}
if( mgrInited ) {
mgrTimer.tmAddr = NULL;
mgrTimer.tmCount = 0;
mgrTimer.tmWakeUp = 0;
mgrTimer.tmReserved = 0;
InsTime( (QElemPtr)&mgrTimer );
PrimeTime( (QElemPtr)&mgrTimer, -MAX_TIME );
}
return( mgrClock );
}
#endif
/***********************************************************/
/* Parsytec GCel timer. */
/* Provided by: Georg Wambach, gw@informatik.uni-koeln.de */
/***********************************************************/
#ifdef PARIX
#include <sys/time.h>
double dtime()
{
double q;
q = (double) (TimeNowHigh()) / (double) CLK_TCK_HIGH;
return q;
}
#endif
/************************************************/
/* Sun Solaris POSIX dtime() routine */
/* Provided by: Case Larsen, CTLarsen.lbl.gov */
/************************************************/
#ifdef POSIX
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/rusage.h>
#ifdef __hpux
#include <sys/syscall.h>
#endif
struct rusage rusage;
double dtime()
{
double q;
getrusage(RUSAGE_SELF,&rusage);
q = (double)(rusage.ru_utime.tv_sec);
q = q + (double)(rusage.ru_utime.tv_nsec) * 1.0e-09;
return q;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -