This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
rfc: -mmemory-latency=
- To: egcs at cygnus dot com
- Subject: rfc: -mmemory-latency=
- From: Richard Henderson <rth at cygnus dot com>
- Date: Fri, 12 Dec 1997 01:05:24 -0800
- Reply-To: egcs at cygnus dot com
I was thinking the other day that, especially on Alpha, memory
scheduling can vary widely for an application.
It would be ideal if GCC knew about caches itself and locality,
and whether it is likely a particular cache line is resident, and
when it might be profitable to do prefetching, etc.
But for now, as a tuning parameter to play around with, here is
a switch that allows the user to change the scheduling parameters.
If there are no objections, I'll check it in to the mainline.
r~
Fri Dec 12 00:34:27 1997 Richard Henderson <rth@cygnus.com>
* alpha.c (alpha_cpu_name): New variable.
(alpha_mlat_string): Likewise.
(alpha_memory_latency): Likewise.
(override_options): Handle -mmemory-latency.
(alpha_adjust_cost): Adjust load cost for latency.
* alpha.h (TARGET_OPTIONS): Add meory-latency.
(REGISTER_MOVE_COST): Define in terms of memory_latency. Take
TARGET_CIX into account.
(MEMORY_MOVE_COST): Define in terms of memory_latency.
* invoke.texi (DEC Alpha Options): Document -mmemory-latency.
* alpha.h (ASM_COMMENT_START): New macro.
Index: gcc/invoke.texi
===================================================================
RCS file: /cvs/cvsfiles/egcs/gcc/invoke.texi,v
retrieving revision 1.21
diff -u -p -d -r1.21 invoke.texi
--- invoke.texi 1997/12/07 00:28:47 1.21
+++ invoke.texi 1997/12/12 08:26:09
@@ -344,6 +344,7 @@ in the following sections.
-mtrap-precision=@var{mode} -mbuild-constants
-mcpu=@var{cpu type}
-mbwx -mno-bwx -mcix -mno-cix -mmax -mno-max
+-mmemory-latency=@var{time}
@emph{Clipper Options}
-mc300 -mc400
@@ -5033,7 +5034,6 @@ CIX, and MAX instruction sets. The defa
supported by the CPU type specified via @samp{-mcpu=} option or that
of the CPU on which GNU CC was built if none was specified.
-@item -mcpu=@var{cpu type}
@item -mcpu=@var{cpu_type}
Set the instruction set, register set, and instruction scheduling
parameters for machine type @var{cpu_type}. You can specify either the
@@ -5059,6 +5059,7 @@ Schedules as an EV5 and has no instructi
Schedules as an EV5 and supports the BWX extension.
@item pca56
+@itemx 21164pc
@itemx 21164PC
Schedules as an EV5 and supports the BWX and MAX extensions.
@@ -5066,6 +5067,29 @@ Schedules as an EV5 and supports the BWX
@itemx 21264
Schedules as an EV5 (until Digital releases the scheduling parameters
for the EV6) and supports the BWX, CIX, and MAX extensions.
+@end table
+
+@item -mmemory-latency=@var{time}
+Sets the latency the scheduler should assume for typical memory
+references as seen by the application. This number is highly
+dependant on the memory access patterns used by the application
+and the size of the external cache on the machine.
+
+Valid options for @var{time} are
+
+@table @samp
+@item @var{number}
+A decimal number representing clock cycles.
+
+@item L1
+@itemx L2
+@itemx L3
+@itemx main
+The compiler contains estimates of the number of clock cycles for
+``typical'' EV4 & EV5 hardware for the Level 1, 2 & 3 caches
+(also called Dcache, Scache, and Bcache), as well as to main memory.
+Note that L3 is only valid for EV5.
+
@end table
@end table
Index: gcc/config/alpha/alpha.c
===================================================================
RCS file: /cvs/cvsfiles/egcs/gcc/config/alpha/alpha.c,v
retrieving revision 1.17
diff -u -p -d -r1.17 alpha.c
--- alpha.c 1997/12/09 05:11:33 1.17
+++ alpha.c 1997/12/12 08:26:10
@@ -22,6 +22,7 @@ Boston, MA 02111-1307, USA. */
#include "config.h"
#include <stdio.h>
+#include <ctype.h>
#include "rtl.h"
#include "regs.h"
#include "hard-reg-set.h"
@@ -47,6 +48,10 @@ extern int rtx_equal_function_value_matt
/* Specify which cpu to schedule for. */
enum processor_type alpha_cpu;
+static char* const alpha_cpu_name[] =
+{
+ "ev4", "ev5", "ev6"
+};
/* Specify how accurate floating-point traps need to be. */
@@ -62,10 +67,11 @@ enum alpha_fp_trap_mode alpha_fptm;
/* Strings decoded into the above options. */
-char *alpha_cpu_string; /* -mcpu=ev[4|5] */
+char *alpha_cpu_string; /* -mcpu= */
char *alpha_tp_string; /* -mtrap-precision=[p|s|i] */
char *alpha_fprm_string; /* -mfp-rounding-mode=[n|m|c|d] */
char *alpha_fptm_string; /* -mfp-trap-mode=[n|u|su|sui] */
+char *alpha_mlat_string; /* -mmemory-latency= */
/* Save information from a "cmpxx" operation until the branch or scc is
emitted. */
@@ -91,6 +97,10 @@ int alpha_function_needs_gp;
static rtx alpha_return_addr_rtx;
+/* The number of cycles of latency we should assume on memory reads. */
+
+int alpha_memory_latency = 3;
+
/* Declarations of static functions. */
static void alpha_set_memflags_1 PROTO((rtx, int, int, int));
static rtx alpha_emit_set_const_1 PROTO((rtx, enum machine_mode,
@@ -243,6 +253,52 @@ override_options ()
alpha_fptm = ALPHA_FPTM_SU;
}
}
+
+ {
+ char *end;
+ int lat;
+
+ if (!alpha_mlat_string)
+ alpha_mlat_string = "L1";
+
+ if (isdigit (alpha_mlat_string[0])
+ && (lat = strtol (alpha_mlat_string, &end, 10), *end == '\0'))
+ ;
+ else if ((alpha_mlat_string[0] == 'L' || alpha_mlat_string[0] == 'l')
+ && isdigit (alpha_mlat_string[1])
+ && alpha_mlat_string[2] == '\0')
+ {
+ static int const cache_latency[][4] =
+ {
+ { 3, 30, -1 }, /* ev4 -- Bcache is a guess */
+ { 2, 12, 38 }, /* ev5 -- Bcache from PC164 LMbench numbers */
+ { 3, 12, -1 }, /* ev6 -- Ho hum, doesn't exist yet */
+ };
+
+ lat = alpha_mlat_string[1] - '0';
+ if (lat < 0 || lat > 3 || cache_latency[alpha_cpu][lat-1] == -1)
+ {
+ warning ("L%d cache latency unknown for %s",
+ lat, alpha_cpu_name[alpha_cpu]);
+ lat = 3;
+ }
+ else
+ lat = cache_latency[alpha_cpu][lat-1];
+ }
+ else if (! strcmp (alpha_mlat_string, "main"))
+ {
+ /* Most current memories have about 370ns latency. This is
+ a reasonable guess for a fast cpu. */
+ lat = 150;
+ }
+ else
+ {
+ warning ("bad value `%s' for -mmemory-latency", alpha_mlat_string);
+ lat = 3;
+ }
+
+ alpha_memory_latency = lat;
+ }
}
/* Returns 1 if VALUE is a mask that contains full bytes of zero or ones. */
@@ -1216,6 +1272,10 @@ alpha_adjust_cost (insn, link, dep_insn,
insn_type = get_attr_type (insn);
dep_insn_type = get_attr_type (dep_insn);
+
+ /* Bring in the user-defined memory latency. */
+ if (dep_insn_type == TYPE_LD || dep_insn_type == TYPE_LDSYM)
+ cost += alpha_memory_latency-1;
if (alpha_cpu == PROCESSOR_EV5)
{
Index: gcc/config/alpha/alpha.h
===================================================================
RCS file: /cvs/cvsfiles/egcs/gcc/config/alpha/alpha.h,v
retrieving revision 1.13
diff -u -p -d -r1.13 alpha.h
--- alpha.h 1997/12/07 00:29:28 1.13
+++ alpha.h 1997/12/12 08:26:10
@@ -245,10 +245,11 @@ extern enum alpha_fp_trap_mode alpha_fpt
extern char *m88k_short_data;
#define TARGET_OPTIONS { { "short-data-", &m88k_short_data } } */
-extern char *alpha_cpu_string; /* For -mcpu=ev[4|5] */
+extern char *alpha_cpu_string; /* For -mcpu= */
extern char *alpha_fprm_string; /* For -mfp-rounding-mode=[n|m|c|d] */
extern char *alpha_fptm_string; /* For -mfp-trap-mode=[n|u|su|sui] */
extern char *alpha_tp_string; /* For -mtrap-precision=[p|f|i] */
+extern char *alpha_mlat_string; /* For -mmemory-latency= */
#define TARGET_OPTIONS \
{ \
@@ -256,6 +257,7 @@ extern char *alpha_tp_string; /* For -mt
{"fp-rounding-mode=", &alpha_fprm_string}, \
{"fp-trap-mode=", &alpha_fptm_string}, \
{"trap-precision=", &alpha_tp_string}, \
+ {"memory-latency=", &alpha_mlat_string}, \
}
/* Sometimes certain combinations of command options do not make sense
@@ -792,15 +794,17 @@ enum reg_class { NO_REGS, GENERAL_REGS,
reduce the impact of not being able to allocate a pseudo to a
hard register. */
-#define REGISTER_MOVE_COST(CLASS1, CLASS2) \
- (((CLASS1) == FLOAT_REGS) == ((CLASS2) == FLOAT_REGS) ? 2 : 20)
+#define REGISTER_MOVE_COST(CLASS1, CLASS2) \
+ (TARGET_CIX || ((CLASS1) == FLOAT_REGS) == ((CLASS2) == FLOAT_REGS) \
+ ? 2 : 4+2*alpha_memory_latency)
/* A C expressions returning the cost of moving data of MODE from a register to
or from memory.
On the Alpha, bump this up a bit. */
-#define MEMORY_MOVE_COST(MODE) 6
+extern int alpha_memory_latency;
+#define MEMORY_MOVE_COST(MODE) (2*alpha_memory_latency)
/* Provide the cost of a branch. Exact meaning under development. */
#define BRANCH_COST 5
@@ -1106,6 +1110,10 @@ extern int alpha_compare_fp_p;
IS_LOCAL is 0 if name is used in call, 1 if name is used in definition. */
extern void alpha_need_linkage ();
+
+/* This macro defines the start of an assembly comment. */
+
+#define ASM_COMMENT_START " #"
/* This macro produces the initial definition of a function name. On the
Alpha, we need to save the function name for the prologue and epilogue. */
Index: gcc/config/alpha/alpha.md
===================================================================
RCS file: /cvs/cvsfiles/egcs/gcc/config/alpha/alpha.md,v
retrieving revision 1.19
diff -u -p -d -r1.19 alpha.md
--- alpha.md 1997/12/09 05:11:34 1.19
+++ alpha.md 1997/12/12 08:26:10
@@ -45,11 +45,13 @@
;; the address, BBOX, used for branches, EBOX, used for integer
;; operations, and FBOX, used for FP operations.
-;; Memory delivers its result in three cycles.
+;; Memory delivers its result in three cycles. Actually return one and
+;; take care of this in adjust_cost, since we want to handle user-defined
+;; memory latencies.
(define_function_unit "ev4_abox" 1 0
(and (eq_attr "cpu" "ev4")
(eq_attr "type" "ld,ldsym,st"))
- 3 1)
+ 1 1)
;; Branches have no delay cost, but do tie up the unit for two cycles.
(define_function_unit "ev4_bbox" 1 1
@@ -127,10 +129,11 @@
1 1)
;; Memory takes at least 2 clocks, and load cannot dual issue with stores.
+;; Return one from here and fix up with user-defined latencies in adjust_cost.
(define_function_unit "ev5_ebox" 2 0
(and (eq_attr "cpu" "ev5")
(eq_attr "type" "ld,ldsym"))
- 2 1)
+ 1 1)
(define_function_unit "ev5_e0" 1 0
(and (eq_attr "cpu" "ev5")