From da7faad5957c45495dcf95e09a26682a60c89933 Mon Sep 17 00:00:00 2001 From: Thomas Roehl Date: Thu, 25 Mar 2021 14:45:15 +0100 Subject: [PATCH 01/16] Delete old files --- clusterdaemon.go | 320 ------------------------------- clusterdaemon_simple.go | 190 ------------------ collectors/likwid.go | 64 ------- collectors/memavg/config.json | 3 - collectors/memavg/read_memavg.go | 48 ----- collectors/memavg/read_memavg.sh | 12 -- 6 files changed, 637 deletions(-) delete mode 100644 clusterdaemon.go delete mode 100644 clusterdaemon_simple.go delete mode 100644 collectors/likwid.go delete mode 100644 collectors/memavg/config.json delete mode 100644 collectors/memavg/read_memavg.go delete mode 100755 collectors/memavg/read_memavg.sh diff --git a/clusterdaemon.go b/clusterdaemon.go deleted file mode 100644 index afe82b8..0000000 --- a/clusterdaemon.go +++ /dev/null @@ -1,320 +0,0 @@ -package main - -import ( - "fmt" - "os" - "os/exec" - - //"bytes" - // "context" - "encoding/json" - "path/filepath" - - //"sort" - "errors" - "strings" - "time" - - protocol "github.com/influxdata/line-protocol" -) - -type GlobalConfig struct { - Sink struct { - User string `json:"user"` - Password string `json:"password"` - } `json:"sink"` - Host string `json:"host"` - Port string `json:"port"` - Report struct { - Levels string `json:"levels"` - Interval int `json:"interval"` - } `json:"report"` - Schedule struct { - Core struct { - Frequency int `json:"frequency"` - Duration int `json:"duration"` - } `json:"core"` - Node struct { - Frequency int `json:"frequency"` - Duration int `json:"duration"` - } `json:"node"` - } `json:"schedule"` - Metrics []string `json:"metrics"` - CollectorPath string `json:"collector_path"` -} - -type CollectorConfig struct { - Command string `json:"command"` - Args string `json:"arguments"` - Provides []string `json:"provides"` -} - -type InternalCollectorConfig struct { - Config CollectorConfig - Location string - LastRun time.Time - encoder *protocol.Encoder -} - -////////////////////////////////////////////////////////////////////////////// -// Load global configuration from JSON file -////////////////////////////////////////////////////////////////////////////// -func LoadGlobalConfiguration(file string, config *GlobalConfig) error { - configFile, err := os.Open(file) - defer configFile.Close() - if err != nil { - return err - } - jsonParser := json.NewDecoder(configFile) - jsonParser.Decode(config) - return err -} - -////////////////////////////////////////////////////////////////////////////// -// Load collector configuration from JSON file -////////////////////////////////////////////////////////////////////////////// -func LoadCollectorConfiguration(file string, config *CollectorConfig) error { - configFile, err := os.Open(file) - defer configFile.Close() - if err != nil { - return err - } - jsonParser := json.NewDecoder(configFile) - jsonParser.Decode(config) - return err -} - -////////////////////////////////////////////////////////////////////////////// -// Load collector configurations -////////////////////////////////////////////////////////////////////////////// -func GetSingleCollector(folders *[]string) filepath.WalkFunc { - return func(path string, info os.FileInfo, err error) error { - if info.IsDir() { - configfile := filepath.Join(path, "config.json") - if _, err := os.Stat(configfile); err == nil { - // TODO: Validate config? - p, err := filepath.Abs(path) - if err == nil { - *folders = append(*folders, p) - } - } - } - return nil - } -} - -func GetCollectorFolders(root string, folders *[]string) error { - err := filepath.Walk(root, GetSingleCollector(folders)) - if err != nil { - err = errors.New("Cannot get collectors") - } - return err -} - -////////////////////////////////////////////////////////////////////////////// -// Setup all collectors -////////////////////////////////////////////////////////////////////////////// -func SetupCollectors(config GlobalConfig) ([]InternalCollectorConfig, error) { - var folders []string - var outconfig []InternalCollectorConfig - //encoder := protocol.NewEncoder(buf) - //encoder.SetMaxLineBytes(1024) - GetCollectorFolders(config.CollectorPath, &folders) - for _, path := range folders { - var col_config InternalCollectorConfig - LoadCollectorConfiguration(filepath.Join(path, "config.json"), &col_config.Config) - col_config.LastRun = time.Now() - col_config.Location = path - //buf := &bytes.Buffer{} - //col_config.Encoder := protocol.NewEncoder(buf) - //col_config.Encoder.SetMaxLineBytes(1024) - outconfig = append(outconfig, col_config) - } - return outconfig, nil -} - -////////////////////////////////////////////////////////////////////////////// -// Run collector -////////////////////////////////////////////////////////////////////////////// -func RunCollector(config InternalCollectorConfig) ([]string, error) { - var results []string - var err error - cmd := config.Config.Command - - if _, err = os.Stat(cmd); err != nil { - //fmt.Println(err.Error()) - if !strings.HasPrefix(cmd, "/") { - cmd = filepath.Join(config.Location, config.Config.Command) - if _, err = os.Stat(cmd); err != nil { - //fmt.Println(err.Error()) - cmd, err = exec.LookPath(config.Config.Command) - } - } - } - if err != nil { - fmt.Println(err.Error()) - return results, err - } - - // TODO: Add timeout - - command := exec.Command(cmd, config.Config.Args) - command.Dir = config.Location - command.Wait() - stdout, err := command.Output() - if err != nil { - //log.error(err.Error()) - fmt.Println(err.Error()) - return results, err - } - - lines := strings.Split(string(stdout), "\n") - - for _, l := range lines { - if strings.HasPrefix(l, "#") { - continue - } - results = append(results, l) - } - return results, err -} - -////////////////////////////////////////////////////////////////////////////// -// Setup sink -////////////////////////////////////////////////////////////////////////////// -func SetupSink(config GlobalConfig) chan string { - - c := make(chan string, 300) - - // TODO: Setup something for sending? Establish HTTP connection? - return c -} - -func RunSink(config GlobalConfig, queue *chan string) (*time.Ticker, chan bool) { - - interval := time.Duration(config.Report.Interval) * time.Second - ticker := time.NewTicker(interval) - done := make(chan bool) - - go func() { - for { - select { - case <-done: - return - case t := <-ticker.C: - fmt.Println("SinkTick at", t) - empty := false - var batch []string - for empty == false { - select { - case metric := <-*queue: - fmt.Println(metric) - batch = append(batch, metric) - default: - // No metric available, wait for the next iteration - empty = true - break - } - } - for _, m := range batch { - fmt.Println(m) - } - } - } - }() - return ticker, done -} - -func CloseSink(config GlobalConfig, queue *chan string, ticker *time.Ticker, done chan bool) { - ticker.Stop() - done <- true - close(*queue) -} - -func MainLoop(config GlobalConfig, sink *chan string) (*time.Ticker, chan bool) { - var intConfig []InternalCollectorConfig - intConfig, err := SetupCollectors(config) - if err != nil { - panic(err) - } - - interval := time.Duration(config.Schedule.Node.Frequency) * time.Second - ticker := time.NewTicker(time.Second) - done := make(chan bool) - - go func() { - for { - select { - case <-done: - return - case t := <-ticker.C: - fmt.Println("CollectorTick at", t) - unix := time.Now() - for i, _ := range intConfig { - if time.Duration(unix.Sub(intConfig[i].LastRun)) > interval { - res, err := RunCollector(intConfig[i]) - if err != nil { - //log.error("Collector failed: ", err.Error()) - } else { - //TODO: parse and skip in case of error, encode to []string - for _, r := range res { - if len(r) > 0 { - *sink <- r - } - } - } - intConfig[i].LastRun = time.Now() - } - } - } - } - }() - return ticker, done -} - -func main() { - // fmt.Println("Hello") - // cmd_opts := []string{"la","le","lu"} - // cmd := "echo" - // s := run_cmd(cmd, cmd_opts) - // fmt.Println(s) - // tags := map[string]string { - // "host" : "broadep2", - // } - // fields := map[string]interface{} { - // "value" : float64(1.0), - // } - // fmt.Println(CreatePoint("flops_any", tags, fields, time.Now().UnixNano())) - var config GlobalConfig - LoadGlobalConfiguration("config.json", &config) - - queue := SetupSink(config) - sinkTicker, sinkDone := RunSink(config, &queue) - collectTicker, collectDone := MainLoop(config, &queue) - time.Sleep(1600 * time.Second) - collectTicker.Stop() - collectDone <- true - CloseSink(config, &queue, sinkTicker, sinkDone) - - // var folders []string - // GetCollectorFolders(config.CollectorPath, &folders) - - // for _, path := range folders { - // var col_config CollectorConfig - // LoadCollectorConfiguration(filepath.Join(path, "config.json"), &col_config) - // stdout := run_cmd(filepath.Join(path, col_config.Command), col_config.Args) - - // metrics := strings.Split(stdout, "\n") - // for _, m := range metrics { - // if len(m) > 0 { - // t := strings.Fields(m) - // if len(t) == 2 { - // var s strings.Builder - // fmt.Fprintf(&s, "%s %d", m, time.Now().UnixNano()) - // m = s.String() - // } - // fmt.Println("SEND", m) - // } - // } - // } -} diff --git a/clusterdaemon_simple.go b/clusterdaemon_simple.go deleted file mode 100644 index 66964e8..0000000 --- a/clusterdaemon_simple.go +++ /dev/null @@ -1,190 +0,0 @@ -package main - -import ( - "fmt" - "strings" - "io/ioutil" - "os" - "os/signal" - "strconv" - "time" -) - - -// geht nicht -//enum CollectScope { -// Node: 0, -// Socket, -// Die, -// LLC, -// NUMA, -// Core, -// HWThread -//} - -//var scopeNames = map[CollectScope]string{ -// Node: "Node", -// Socket: "Socket", -// Die: "Die", -// LLC: "LLC", -// NUMA: "NUMA", -// Core: "Core", -// HWThread: "HWThread" -//} - -type CollectValue struct { - Name string - Value interface{} - //scope CollectScope -} - -type InitFunc func() error -type ReadFunc func(time.Duration) ([]CollectValue, error) -type CloseFunc func() error -type SinkFunc func([]CollectValue) error - -func read_memavg(duration time.Duration) ([]CollectValue, error) { - var values []CollectValue - data, err := ioutil.ReadFile("/proc/meminfo") - if err != nil { - fmt.Println(err.Error()) - return values, err - } - var matches = map[string]string { - "MemTotal" : "mem_total", - "MemAvailable" : "mem_avail", - "MemFree" : "mem_free", - } - lines := strings.Split(string(data), "\n") - for _, l := range lines { - for i,o := range matches { - if strings.HasPrefix(l, i) { - f := strings.Fields(l) - v, err := strconv.ParseInt(f[1], 10, 0) - if err == nil { - var value CollectValue - // value.Scope = Node - value.Name = o - value.Value = v - values = append(values, value) - } - } - } - } - return values, nil -} - -func read_loadavg(duration time.Duration) ([]CollectValue, error) { - var values []CollectValue - data, err := ioutil.ReadFile("/proc/loadavg") - if err != nil { - fmt.Println(err.Error()) - return values, err - } - var matches = map[int]string { - 0 : "loadavg1m", - 1 : "loadavg5m", - 2 : "loadavg15m", - } - f := strings.Fields(string(data)) - for i, m := range matches { - v, err := strconv.ParseFloat(f[i], 64) - if err == nil { - var value CollectValue - value.Name = m - value.Value = v - // value.Scope = Node - values = append(values, value) - } - } - return values, nil -} - -func read_netstat(duration time.Duration) ([]CollectValue, error) { - var values []CollectValue - data, err := ioutil.ReadFile("/proc/net/dev") - if err != nil { - fmt.Println(err.Error()) - return values, err - } - var matches = map[int]string { - 1 : "bytes_in", - 9 : "bytes_out", - 2 : "pkts_in", - 10 : "pkts_out", - } - lines := strings.Split(string(data), "\n") - for _, l := range lines { - if ! strings.Contains(l, ":") { - continue - } - f := strings.Fields(l) - dev := f[0][0:len(f[0])-1] - if dev == "lo" { - continue - } - for i, m := range matches { - v, err := strconv.ParseInt(f[i], 10, 0) - if err == nil { - var value CollectValue - value.Name = fmt.Sprintf("%s_%s", dev, m) - value.Value = v - //value.Scope = Node - values = append(values, value) - } - } - } - return values, nil -} - -func Send(values []CollectValue) error { - for _, v := range values { - fmt.Printf("Name: '%s' Value: '%v'\n", v.Name, v.Value) - } - return nil -} - -func ReadAll(duration time.Duration, reads []ReadFunc, sink SinkFunc) { - for _, f := range reads { - values, err := f(duration) - if err == nil { - sink(values) - } - } -} - -func ReadLoop(interval time.Duration, duration time.Duration, reads []ReadFunc, sink SinkFunc) { - ticker := time.NewTicker(interval) - done := make(chan bool) - sigs := make(chan os.Signal, 1) - signal.Notify(sigs, os.Interrupt) - ReadAll(duration, reads, sink) - go func() { - <-sigs - // Should call all CloseFunc functions here - os.Exit(1) - }() - func() { - select { - case <-done: - return - case t := <-ticker.C: - fmt.Println("Tick at", t) - ReadAll(duration, reads, sink) - } - }() - ticker.Stop() - done <- true -} - -func main() { - //var inits []InitFunc - var reads = []ReadFunc {read_memavg, read_loadavg, read_netstat} - //var closes []CloseFunc - var duration time.Duration - var interval time.Duration - duration = time.Duration(1) * time.Second - interval = time.Duration(10) * time.Second - ReadLoop(interval, duration, reads, Send) - return -} diff --git a/collectors/likwid.go b/collectors/likwid.go deleted file mode 100644 index 829b5c3..0000000 --- a/collectors/likwid.go +++ /dev/null @@ -1,64 +0,0 @@ -package collectors - -import ( - "bytes" - "fmt" - "time" - - protocol "github.com/influxdata/line-protocol" -) - -type LikwidCollector struct { - name string - tags []*protocol.Tag - fields []*protocol.Field - t time.Time - encoder *protocol.Encoder -} - -func (c *LikwidCollector) Name() string { - return c.name -} -func (c *LikwidCollector) TagList() []*protocol.Tag { - return c.tags -} - -func (c *LikwidCollector) FieldList() []*protocol.Field { - return c.fields -} - -func (c *LikwidCollector) Time() time.Time { - return c.t -} - -func (c *LikwidCollector) New() { - buf := &bytes.Buffer{} - c.encoder = protocol.NewEncoder(buf) - c.encoder.SetMaxLineBytes(1024) -} - -func (c *LikwidCollector) Start( - level string, - frequency time.Duration, - duration int) { - ticker := time.NewTicker(frequency * time.Second) - done := make(chan bool) - - go func() { - for { - select { - case <-done: - return - case t := <-ticker.C: - fmt.Println("Tick at", t) - - c.encoder.Encode(c) - } - } - }() - - time.Sleep(1600 * time.Second) - ticker.Stop() - done <- true - fmt.Println("Ticker stopped") -} diff --git a/collectors/memavg/config.json b/collectors/memavg/config.json deleted file mode 100644 index a1b8ffb..0000000 --- a/collectors/memavg/config.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "command": "read_memavg.sh" -} diff --git a/collectors/memavg/read_memavg.go b/collectors/memavg/read_memavg.go deleted file mode 100644 index 9590878..0000000 --- a/collectors/memavg/read_memavg.go +++ /dev/null @@ -1,48 +0,0 @@ -package main -import ( - "strings" - "io/ioutil" - "fmt" - "time" - "os" - "strconv" - ) - -func main() { - t := time.Now() - hostname, err := os.Hostname() - if err != nil { - fmt.Println("#", err) - os.Exit(1) - } - hostname = strings.Split(hostname, ".")[0] - data, err := ioutil.ReadFile("/proc/meminfo") - if err != nil { - fmt.Println("#", err) - os.Exit(1) - return - } - lines := strings.Split(string(data), "\n") - for _, l := range lines { - if strings.HasPrefix(l, "MemTotal") { - f := strings.Fields(l) - v, err := strconv.ParseInt(f[1], 10, 0) - if err == nil { - fmt.Printf("mem_total,hostname=%s value=%v %v\n", hostname, v*1024, t.UnixNano()) - } - } else if strings.HasPrefix(l, "MemAvailable") { - f := strings.Fields(l) - v, err := strconv.ParseInt(f[1], 10, 0) - if err == nil { - fmt.Printf("mem_avail,hostname=%s value=%v %v\n", hostname, v*1024, t.UnixNano()) - } - } else if strings.HasPrefix(l, "MemFree") { - f := strings.Fields(l) - v, err := strconv.ParseInt(f[1], 10, 0) - if err == nil { - fmt.Printf("mem_free,hostname=%s value=%v %v\n", hostname, v*1024, t.UnixNano()) - } - } - } - return -} diff --git a/collectors/memavg/read_memavg.sh b/collectors/memavg/read_memavg.sh deleted file mode 100755 index d2f3db1..0000000 --- a/collectors/memavg/read_memavg.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/bash - - -TOTAL=$(grep "MemTotal" /proc/meminfo | awk '{print $2}') -AVAIL=$(grep "MemAvailable" /proc/meminfo | awk '{print $2}') -FREE=$(grep "MemFree" /proc/meminfo | awk '{print $2}') -HOST=$(hostname -s) - - -echo "mem_total,host=$HOST value=$TOTAL" -echo "mem_avail,host=$HOST value=$AVAIL" -echo "mem_free,host=$HOST value=$FREE" From 1c7aa6477bdd4e2a7e0433c1fe004da8089d6d94 Mon Sep 17 00:00:00 2001 From: Thomas Roehl Date: Thu, 25 Mar 2021 14:46:21 +0100 Subject: [PATCH 02/16] Add collectors base type --- collectors/metricCollector.go | 119 ++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 collectors/metricCollector.go diff --git a/collectors/metricCollector.go b/collectors/metricCollector.go new file mode 100644 index 0000000..91df630 --- /dev/null +++ b/collectors/metricCollector.go @@ -0,0 +1,119 @@ +package collectors + +import ( + "time" + "io/ioutil" + "strings" + "log" + "strconv" +) + +type MetricGetter interface { + Name() string + Init() + Read(time.Duration) + Close() + GetNodeMetric() map[string]interface{} + GetSocketMetrics() map[int]map[string]interface{} + GetCpuMetrics() map[int]map[string]interface{} +} + +type MetricCollector struct { + name string + node map[string]interface{} + sockets map[int]map[string]interface{} + cpus map[int]map[string]interface{} +} + + + +func (c *MetricCollector) Name() string { + return c.name +} + +func (c *MetricCollector) GetNodeMetric() map[string]interface{} { + return c.node +} + +func (c *MetricCollector) GetSocketMetrics() map[int]map[string]interface{} { + return c.sockets +} + +func (c *MetricCollector) GetCpuMetrics() map[int]map[string]interface{} { + return c.cpus +} + +func (c *MetricCollector) setup() error { + slist := SocketList() + clist := CpuList() + c.node = make(map[string]interface{}) + c.sockets = make(map[int]map[string]interface{}, len(slist)) + for _, s := range slist { + c.sockets[s] = make(map[string]interface{}) + } + c.cpus = make(map[int]map[string]interface{}, len(clist)) + for _, s := range clist { + c.cpus[s] = make(map[string]interface{}) + } + return nil +} + + +func intArrayContains(array []int, str int) (int, bool) { + for i, a := range array { + if a == str { + return i, true + } + } + return -1, false +} + +func SocketList() []int { + buffer, err := ioutil.ReadFile("/proc/cpuinfo") + if err != nil { + log.Print(err) + return nil + } + ll := strings.Split(string(buffer), "\n") + var packs []int + for _, line := range ll { + if strings.HasPrefix(line, "physical id") { + lv := strings.Fields(line) + id, err := strconv.ParseInt(lv[3], 10, 32) + if err != nil { + log.Print(err) + return packs + } + _, found := intArrayContains(packs, int(id)) + if !found { + packs = append(packs, int(id)) + } + } + } + return packs +} + +func CpuList() []int { + buffer, err := ioutil.ReadFile("/proc/cpuinfo") + if err != nil { + log.Print(err) + return nil + } + ll := strings.Split(string(buffer), "\n") + var cpulist []int + for _, line := range ll { + if strings.HasPrefix(line, "processor") { + lv := strings.Fields(line) + id, err := strconv.ParseInt(lv[2], 10, 32) + if err != nil { + log.Print(err) + return cpulist + } + _, found := intArrayContains(cpulist, int(id)) + if !found { + cpulist = append(cpulist, int(id)) + } + } + } + return cpulist +} From 4fddcb974166491c51a80800e9c4311597402826 Mon Sep 17 00:00:00 2001 From: Thomas Roehl Date: Thu, 25 Mar 2021 14:46:25 +0100 Subject: [PATCH 03/16] Add main with ticker --- metric-collector.go | 181 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 181 insertions(+) create mode 100644 metric-collector.go diff --git a/metric-collector.go b/metric-collector.go new file mode 100644 index 0000000..2eecdb9 --- /dev/null +++ b/metric-collector.go @@ -0,0 +1,181 @@ +package main + +import ( + "encoding/json" + "fmt" + "log" + "os" + "os/signal" + "sync" + "time" + "github.com/ClusterCockpit/cc-metric-collector/collectors" + protocol "github.com/influxdata/line-protocol" +) + +var Collectors = map[string]collectors.MetricGetter{ + "likwid": &collectors.LikwidCollector{}, + "loadavg": &collectors.LoadavgCollector{}, + "memstat": &collectors.MemstatCollector{}, + "netstat": &collectors.NetstatCollector{}, +} +type GlobalConfig struct { + Sink struct { + User string `json:"user"` + Password string `json:"password"` + Host string `json:"host"` + Port string `json:"port"` + } `json:"sink"` + Interval int `json:"interval"` + Duration int `json:"duration"` + Collectors []string `json:"collectors"` +} + + + +func LoadConfiguration(file string, config *GlobalConfig) error { + configFile, err := os.Open(file) + defer configFile.Close() + if err != nil { + fmt.Println(err.Error()) + } + jsonParser := json.NewDecoder(configFile) + jsonParser.Decode(config) + return err +} + + + +func shutdown(wg *sync.WaitGroup, config *GlobalConfig) { + sigs := make(chan os.Signal, 1) + signal.Notify(sigs, os.Interrupt) + + go func(wg *sync.WaitGroup) { + <-sigs + log.Print("Shutdown...") + for _, c := range config.Collectors { + col := Collectors[c] + log.Print("Stop ", col.Name()) + col.Close() + } + time.Sleep(1 * time.Second) + wg.Done() + }(wg) +} + +func main() { + var config GlobalConfig + var wg sync.WaitGroup + wg.Add(1) + host, err := os.Hostname() + if err != nil { + log.Print(err) + return + } + var tags = map[string]string {"host": host} + + LoadConfiguration("config.json", &config) + if config.Interval <= 0 || time.Duration(config.Interval) * time.Second <= 0 { + log.Print("Configuration value 'interval' must be greater than zero") + return + } + if config.Duration <= 0 { + log.Print("Configuration value 'duration' must be greater than zero") + return + } + shutdown(&wg, &config) + serializer := protocol.NewEncoder(os.Stdout) + serializer.SetPrecision(time.Second) + serializer.SetMaxLineBytes(1024) + for _, c := range config.Collectors { + col := Collectors[c] + col.Init() + log.Print("Start ", col.Name()) + } + log.Print(config.Interval, time.Duration(config.Interval) * time.Second) + ticker := time.NewTicker(time.Duration(config.Interval) * time.Second) + done := make(chan bool) + node_fields := make(map[string]interface{}) + slist := collectors.SocketList() + sockets_fields := make(map[int]map[string]interface{}, len(slist)) + for _, s := range slist { + sockets_fields[s] = make(map[string]interface{}) + } + clist := collectors.CpuList() + cpu_fields := make(map[int]map[string]interface{}, len(clist)) + for _, s := range clist { + cpu_fields[s] = make(map[string]interface{}) + } + + go func() { + for { + select { + case <-done: + return + case t:= <-ticker.C: + + + scount := 0 + ccount := 0 + for _, c := range config.Collectors { + col := Collectors[c] + col.Read(time.Duration(config.Duration)) + for key, val := range col.GetNodeMetric() { + node_fields[key] = val + } + for sid, socket := range col.GetSocketMetrics() { + for key, val := range socket { + sockets_fields[sid][key] = val + scount++ + } + } + for cid, cpu := range col.GetCpuMetrics() { + for key, val := range cpu { + cpu_fields[cid][key] = val + ccount++ + } + } + } + var CurrentNode protocol.MutableMetric + CurrentNode, err = protocol.New("node", tags, node_fields, t) + if err != nil { + log.Print(err) + } + _, err := serializer.Encode(CurrentNode) + if err != nil { + log.Print(err) + } + if scount > 0 { + for sid, socket := range sockets_fields { + var CurrentSocket protocol.MutableMetric + var stags = map[string]string {"socket": fmt.Sprintf("%d", sid), "host": host} + CurrentSocket, err = protocol.New("socket", stags, socket, t) + if err != nil { + log.Print(err) + } + _, err := serializer.Encode(CurrentSocket) + if err != nil { + log.Print(err) + } + } + } + if ccount > 0 { + for cid, cpu := range cpu_fields { + var CurrentCpu protocol.MutableMetric + var ctags = map[string]string {"host": host, "cpu": fmt.Sprintf("%d", cid)} + CurrentCpu, err = protocol.New("cpu", ctags, cpu, t) + if err != nil { + log.Print(err) + } + _, err := serializer.Encode(CurrentCpu) + if err != nil { + log.Print(err) + } + } + } + } + } + }() + + + wg.Wait() +} From a6ac0c5373e31f99c743dacc1b39730fae6195e2 Mon Sep 17 00:00:00 2001 From: Thomas Roehl Date: Thu, 25 Mar 2021 14:47:10 +0100 Subject: [PATCH 04/16] Add likwid collector --- collectors/likwid/bstrlib.h | 301 +++ collectors/likwid/groups/CLX/BRANCH.txt | 31 + collectors/likwid/groups/CLX/CACHES.txt | 143 + collectors/likwid/groups/CLX/CLOCK.txt | 26 + .../likwid/groups/CLX/CYCLE_ACTIVITY.txt | 38 + collectors/likwid/groups/CLX/CYCLE_STALLS.txt | 45 + collectors/likwid/groups/CLX/DATA.txt | 22 + collectors/likwid/groups/CLX/DIVIDE.txt | 24 + collectors/likwid/groups/CLX/ENERGY.txt | 35 + collectors/likwid/groups/CLX/FLOPS_AVX.txt | 25 + collectors/likwid/groups/CLX/FLOPS_DP.txt | 34 + collectors/likwid/groups/CLX/FLOPS_SP.txt | 34 + collectors/likwid/groups/CLX/L2.txt | 38 + collectors/likwid/groups/CLX/L2CACHE.txt | 34 + collectors/likwid/groups/CLX/L3.txt | 36 + collectors/likwid/groups/CLX/L3CACHE.txt | 35 + collectors/likwid/groups/CLX/MEM.txt | 48 + collectors/likwid/groups/CLX/MEM_DP.txt | 70 + collectors/likwid/groups/CLX/MEM_SP.txt | 70 + collectors/likwid/groups/CLX/PMM.txt | 46 + collectors/likwid/groups/CLX/TLB_DATA.txt | 35 + collectors/likwid/groups/CLX/TLB_INSTR.txt | 28 + collectors/likwid/groups/CLX/TMA.txt | 48 + collectors/likwid/groups/CLX/UOPS_EXEC.txt | 31 + collectors/likwid/groups/CLX/UOPS_ISSUE.txt | 31 + collectors/likwid/groups/CLX/UOPS_RETIRE.txt | 31 + collectors/likwid/groups/CLX/UPI.txt | 42 + collectors/likwid/groups/ICL/BRANCH.txt | 31 + collectors/likwid/groups/ICL/DATA.txt | 22 + collectors/likwid/groups/ICL/DIVIDE.txt | 24 + collectors/likwid/groups/ICL/ENERGY.txt | 35 + collectors/likwid/groups/ICL/FLOPS_AVX.txt | 25 + collectors/likwid/groups/ICL/FLOPS_DP.txt | 34 + collectors/likwid/groups/ICL/FLOPS_SP.txt | 34 + collectors/likwid/groups/ICX/BRANCH.txt | 32 + collectors/likwid/groups/ICX/DATA.txt | 23 + collectors/likwid/groups/ICX/DIVIDE.txt | 25 + collectors/likwid/groups/ICX/FLOPS_AVX.txt | 26 + collectors/likwid/groups/ICX/FLOPS_DP.txt | 35 + collectors/likwid/groups/ICX/FLOPS_SP.txt | 35 + collectors/likwid/groups/ICX/L2.txt | 39 + collectors/likwid/groups/TGL/BRANCH.txt | 31 + collectors/likwid/groups/TGL/DATA.txt | 22 + collectors/likwid/groups/TGL/DIVIDE.txt | 24 + collectors/likwid/groups/TGL/ENERGY.txt | 35 + collectors/likwid/groups/TGL/FLOPS_AVX.txt | 25 + collectors/likwid/groups/TGL/FLOPS_DP.txt | 34 + collectors/likwid/groups/TGL/FLOPS_SP.txt | 34 + collectors/likwid/groups/arm64fx/BRANCH.txt | 30 + collectors/likwid/groups/arm64fx/DATA.txt | 24 + collectors/likwid/groups/arm64fx/FLOPS_DP.txt | 26 + collectors/likwid/groups/arm64fx/FLOPS_HP.txt | 26 + collectors/likwid/groups/arm64fx/FLOPS_SP.txt | 26 + collectors/likwid/groups/arm64fx/FP_PIPE.txt | 33 + collectors/likwid/groups/arm64fx/ICACHE.txt | 24 + collectors/likwid/groups/arm64fx/L2.txt | 40 + collectors/likwid/groups/arm64fx/MEM.txt | 29 + collectors/likwid/groups/arm64fx/MEM_DP.txt | 50 + collectors/likwid/groups/arm64fx/MEM_HP.txt | 50 + collectors/likwid/groups/arm64fx/MEM_SP.txt | 50 + collectors/likwid/groups/arm64fx/PCI.txt | 29 + collectors/likwid/groups/arm64fx/TOFU.txt | 29 + collectors/likwid/groups/arm8/BRANCH.txt | 31 + collectors/likwid/groups/arm8/DATA.txt | 24 + collectors/likwid/groups/arm8/ICACHE.txt | 24 + collectors/likwid/groups/arm8/L2.txt | 40 + collectors/likwid/groups/arm8/MEM.txt | 30 + collectors/likwid/groups/arm8_n1/BRANCH.txt | 31 + collectors/likwid/groups/arm8_n1/CLOCK.txt | 16 + collectors/likwid/groups/arm8_n1/DATA.txt | 24 + collectors/likwid/groups/arm8_n1/ICACHE.txt | 24 + collectors/likwid/groups/arm8_n1/L2.txt | 40 + collectors/likwid/groups/arm8_n1/L3.txt | 30 + collectors/likwid/groups/arm8_n1/MEM.txt | 29 + collectors/likwid/groups/arm8_n1/TLB.txt | 30 + collectors/likwid/groups/arm8_tx2/BRANCH.txt | 32 + collectors/likwid/groups/arm8_tx2/DATA.txt | 25 + .../likwid/groups/arm8_tx2/FLOPS_DP.txt | 28 + .../likwid/groups/arm8_tx2/FLOPS_SP.txt | 28 + collectors/likwid/groups/arm8_tx2/ICACHE.txt | 23 + collectors/likwid/groups/arm8_tx2/L2.txt | 41 + collectors/likwid/groups/arm8_tx2/L2CACHE.txt | 32 + collectors/likwid/groups/arm8_tx2/L3.txt | 38 + collectors/likwid/groups/arm8_tx2/MEM.txt | 32 + collectors/likwid/groups/arm8_tx2/SPEC.txt | 44 + .../likwid/groups/arm8_tx2/TLB_DATA.txt | 27 + .../likwid/groups/arm8_tx2/TLB_INSTR.txt | 23 + collectors/likwid/groups/atom/BRANCH.txt | 29 + collectors/likwid/groups/atom/DATA.txt | 20 + collectors/likwid/groups/atom/FLOPS_DP.txt | 25 + collectors/likwid/groups/atom/FLOPS_SP.txt | 24 + collectors/likwid/groups/atom/FLOPS_X87.txt | 19 + collectors/likwid/groups/atom/MEM.txt | 21 + collectors/likwid/groups/atom/TLB.txt | 21 + collectors/likwid/groups/broadwell/BRANCH.txt | 31 + collectors/likwid/groups/broadwell/CLOCK.txt | 26 + .../groups/broadwell/CYCLE_ACTIVITY.txt | 38 + .../likwid/groups/broadwell/CYCLE_STALLS.txt | 45 + collectors/likwid/groups/broadwell/DATA.txt | 22 + collectors/likwid/groups/broadwell/DIVIDE.txt | 24 + collectors/likwid/groups/broadwell/ENERGY.txt | 39 + .../likwid/groups/broadwell/FALSE_SHARE.txt | 25 + .../likwid/groups/broadwell/FLOPS_AVX.txt | 24 + .../likwid/groups/broadwell/FLOPS_DP.txt | 31 + .../likwid/groups/broadwell/FLOPS_SP.txt | 31 + collectors/likwid/groups/broadwell/ICACHE.txt | 25 + collectors/likwid/groups/broadwell/L2.txt | 37 + .../likwid/groups/broadwell/L2CACHE.txt | 34 + collectors/likwid/groups/broadwell/L3.txt | 36 + .../likwid/groups/broadwell/L3CACHE.txt | 35 + .../likwid/groups/broadwell/PORT_USAGE.txt | 50 + .../likwid/groups/broadwell/RECOVERY.txt | 22 + .../likwid/groups/broadwell/TLB_DATA.txt | 35 + .../likwid/groups/broadwell/TLB_INSTR.txt | 28 + collectors/likwid/groups/broadwell/TMA.txt | 48 + collectors/likwid/groups/broadwell/UOPS.txt | 35 + .../likwid/groups/broadwellD/BRANCH.txt | 31 + .../likwid/groups/broadwellD/CACHES.txt | 123 + collectors/likwid/groups/broadwellD/CLOCK.txt | 26 + .../groups/broadwellD/CYCLE_ACTIVITY.txt | 38 + .../likwid/groups/broadwellD/CYCLE_STALLS.txt | 45 + collectors/likwid/groups/broadwellD/DATA.txt | 22 + .../likwid/groups/broadwellD/DIVIDE.txt | 24 + .../likwid/groups/broadwellD/ENERGY.txt | 39 + .../likwid/groups/broadwellD/FALSE_SHARE.txt | 25 + .../likwid/groups/broadwellD/FLOPS_AVX.txt | 24 + .../likwid/groups/broadwellD/FLOPS_DP.txt | 31 + .../likwid/groups/broadwellD/FLOPS_SP.txt | 31 + collectors/likwid/groups/broadwellD/HA.txt | 40 + .../likwid/groups/broadwellD/ICACHE.txt | 25 + collectors/likwid/groups/broadwellD/L2.txt | 37 + .../likwid/groups/broadwellD/L2CACHE.txt | 34 + collectors/likwid/groups/broadwellD/L3.txt | 36 + .../likwid/groups/broadwellD/L3CACHE.txt | 35 + collectors/likwid/groups/broadwellD/MEM.txt | 52 + .../likwid/groups/broadwellD/MEM_DP.txt | 73 + .../likwid/groups/broadwellD/MEM_SP.txt | 73 + .../likwid/groups/broadwellD/PORT_USAGE.txt | 50 + .../likwid/groups/broadwellD/RECOVERY.txt | 22 + .../likwid/groups/broadwellD/TLB_DATA.txt | 35 + .../likwid/groups/broadwellD/TLB_INSTR.txt | 28 + collectors/likwid/groups/broadwellD/TMA.txt | 48 + collectors/likwid/groups/broadwellD/UOPS.txt | 35 + .../likwid/groups/broadwellEP/BRANCH.txt | 31 + .../likwid/groups/broadwellEP/CACHES.txt | 135 + .../likwid/groups/broadwellEP/CLOCK.txt | 26 + .../groups/broadwellEP/CYCLE_ACTIVITY.txt | 38 + .../groups/broadwellEP/CYCLE_STALLS.txt | 45 + collectors/likwid/groups/broadwellEP/DATA.txt | 22 + .../likwid/groups/broadwellEP/DIVIDE.txt | 24 + .../likwid/groups/broadwellEP/ENERGY.txt | 35 + .../likwid/groups/broadwellEP/FALSE_SHARE.txt | 30 + .../likwid/groups/broadwellEP/FLOPS_AVX.txt | 24 + .../likwid/groups/broadwellEP/FLOPS_DP.txt | 31 + .../likwid/groups/broadwellEP/FLOPS_SP.txt | 31 + collectors/likwid/groups/broadwellEP/HA.txt | 40 + .../likwid/groups/broadwellEP/ICACHE.txt | 25 + collectors/likwid/groups/broadwellEP/L2.txt | 37 + .../likwid/groups/broadwellEP/L2CACHE.txt | 34 + collectors/likwid/groups/broadwellEP/L3.txt | 36 + .../likwid/groups/broadwellEP/L3CACHE.txt | 35 + collectors/likwid/groups/broadwellEP/MEM.txt | 52 + .../likwid/groups/broadwellEP/MEM_DP.txt | 73 + .../likwid/groups/broadwellEP/MEM_SP.txt | 73 + collectors/likwid/groups/broadwellEP/NUMA.txt | 41 + .../likwid/groups/broadwellEP/PORT_USAGE.txt | 50 + collectors/likwid/groups/broadwellEP/QPI.txt | 49 + .../likwid/groups/broadwellEP/TLB_DATA.txt | 35 + .../likwid/groups/broadwellEP/TLB_INSTR.txt | 28 + collectors/likwid/groups/broadwellEP/TMA.txt | 48 + collectors/likwid/groups/broadwellEP/UOPS.txt | 35 + collectors/likwid/groups/core2/BRANCH.txt | 30 + collectors/likwid/groups/core2/CACHE.txt | 34 + collectors/likwid/groups/core2/CLOCK.txt | 19 + collectors/likwid/groups/core2/DATA.txt | 22 + collectors/likwid/groups/core2/DIVIDE.txt | 24 + collectors/likwid/groups/core2/FLOPS_DP.txt | 29 + collectors/likwid/groups/core2/FLOPS_SP.txt | 29 + collectors/likwid/groups/core2/FLOPS_X87.txt | 21 + collectors/likwid/groups/core2/L2.txt | 35 + collectors/likwid/groups/core2/L2CACHE.txt | 34 + collectors/likwid/groups/core2/MEM.txt | 23 + collectors/likwid/groups/core2/TLB.txt | 29 + collectors/likwid/groups/core2/UOPS.txt | 26 + .../likwid/groups/core2/UOPS_RETIRE.txt | 25 + collectors/likwid/groups/goldmont/BRANCH.txt | 31 + collectors/likwid/groups/goldmont/CLOCK.txt | 23 + collectors/likwid/groups/goldmont/DATA.txt | 22 + collectors/likwid/groups/goldmont/DIVIDE.txt | 24 + collectors/likwid/groups/goldmont/ENERGY.txt | 33 + collectors/likwid/groups/goldmont/ICACHE.txt | 25 + collectors/likwid/groups/goldmont/L2CACHE.txt | 34 + .../likwid/groups/goldmont/TLB_DATA.txt | 27 + .../likwid/groups/goldmont/TLB_INSTR.txt | 27 + collectors/likwid/groups/haswell/BRANCH.txt | 31 + collectors/likwid/groups/haswell/CACHES.txt | 71 + collectors/likwid/groups/haswell/CLOCK.txt | 26 + .../likwid/groups/haswell/CYCLE_ACTIVITY.txt | 38 + .../likwid/groups/haswell/CYCLE_STALLS.txt | 45 + collectors/likwid/groups/haswell/DATA.txt | 27 + collectors/likwid/groups/haswell/DIVIDE.txt | 24 + collectors/likwid/groups/haswell/ENERGY.txt | 39 + .../likwid/groups/haswell/FALSE_SHARE.txt | 27 + .../likwid/groups/haswell/FLOPS_AVX.txt | 28 + collectors/likwid/groups/haswell/ICACHE.txt | 33 + collectors/likwid/groups/haswell/L2.txt | 37 + collectors/likwid/groups/haswell/L2CACHE.txt | 34 + collectors/likwid/groups/haswell/L3.txt | 36 + collectors/likwid/groups/haswell/L3CACHE.txt | 35 + collectors/likwid/groups/haswell/MEM.txt | 36 + .../likwid/groups/haswell/PORT_USAGE.txt | 46 + collectors/likwid/groups/haswell/RECOVERY.txt | 22 + collectors/likwid/groups/haswell/TLB_DATA.txt | 35 + .../likwid/groups/haswell/TLB_INSTR.txt | 28 + collectors/likwid/groups/haswell/TMA.txt | 48 + collectors/likwid/groups/haswell/UOPS.txt | 35 + .../likwid/groups/haswell/UOPS_EXEC.txt | 31 + .../likwid/groups/haswell/UOPS_ISSUE.txt | 31 + .../likwid/groups/haswell/UOPS_RETIRE.txt | 31 + collectors/likwid/groups/haswellEP/BRANCH.txt | 31 + collectors/likwid/groups/haswellEP/CACHES.txt | 123 + collectors/likwid/groups/haswellEP/CBOX.txt | 61 + collectors/likwid/groups/haswellEP/CLOCK.txt | 26 + .../groups/haswellEP/CYCLE_ACTIVITY.txt | 38 + .../likwid/groups/haswellEP/CYCLE_STALLS.txt | 45 + collectors/likwid/groups/haswellEP/DATA.txt | 22 + collectors/likwid/groups/haswellEP/DIVIDE.txt | 24 + collectors/likwid/groups/haswellEP/ENERGY.txt | 35 + .../likwid/groups/haswellEP/FALSE_SHARE.txt | 34 + .../likwid/groups/haswellEP/FLOPS_AVX.txt | 28 + collectors/likwid/groups/haswellEP/HA.txt | 40 + collectors/likwid/groups/haswellEP/ICACHE.txt | 33 + collectors/likwid/groups/haswellEP/L2.txt | 37 + .../likwid/groups/haswellEP/L2CACHE.txt | 34 + collectors/likwid/groups/haswellEP/L3.txt | 36 + .../likwid/groups/haswellEP/L3CACHE.txt | 35 + collectors/likwid/groups/haswellEP/MEM.txt | 52 + collectors/likwid/groups/haswellEP/NUMA.txt | 33 + .../likwid/groups/haswellEP/PORT_USAGE.txt | 46 + collectors/likwid/groups/haswellEP/QPI.txt | 49 + .../likwid/groups/haswellEP/RECOVERY.txt | 22 + collectors/likwid/groups/haswellEP/SBOX.txt | 28 + .../likwid/groups/haswellEP/TLB_DATA.txt | 35 + .../likwid/groups/haswellEP/TLB_INSTR.txt | 28 + collectors/likwid/groups/haswellEP/TMA.txt | 48 + collectors/likwid/groups/haswellEP/UOPS.txt | 35 + .../likwid/groups/haswellEP/UOPS_EXEC.txt | 31 + .../likwid/groups/haswellEP/UOPS_ISSUE.txt | 31 + .../likwid/groups/haswellEP/UOPS_RETIRE.txt | 31 + .../likwid/groups/interlagos/BRANCH.txt | 26 + collectors/likwid/groups/interlagos/CACHE.txt | 32 + collectors/likwid/groups/interlagos/CPI.txt | 26 + collectors/likwid/groups/interlagos/DATA.txt | 16 + .../likwid/groups/interlagos/FLOPS_DP.txt | 23 + .../likwid/groups/interlagos/FLOPS_SP.txt | 23 + .../groups/interlagos/FPU_EXCEPTION.txt | 21 + .../likwid/groups/interlagos/ICACHE.txt | 23 + collectors/likwid/groups/interlagos/L2.txt | 29 + .../likwid/groups/interlagos/L2CACHE.txt | 31 + collectors/likwid/groups/interlagos/L3.txt | 29 + .../likwid/groups/interlagos/L3CACHE.txt | 35 + collectors/likwid/groups/interlagos/LINKS.txt | 26 + collectors/likwid/groups/interlagos/MEM.txt | 20 + collectors/likwid/groups/interlagos/NUMA.txt | 28 + .../likwid/groups/interlagos/NUMA_0_3.txt | 28 + .../likwid/groups/interlagos/NUMA_4_7.txt | 28 + collectors/likwid/groups/ivybridge/BRANCH.txt | 31 + collectors/likwid/groups/ivybridge/CLOCK.txt | 26 + .../groups/ivybridge/CYCLE_ACTIVITY.txt | 38 + .../likwid/groups/ivybridge/CYCLE_STALLS.txt | 45 + collectors/likwid/groups/ivybridge/DATA.txt | 22 + collectors/likwid/groups/ivybridge/DIVIDE.txt | 24 + collectors/likwid/groups/ivybridge/ENERGY.txt | 37 + .../likwid/groups/ivybridge/FALSE_SHARE.txt | 25 + .../likwid/groups/ivybridge/FLOPS_AVX.txt | 25 + .../likwid/groups/ivybridge/FLOPS_DP.txt | 33 + .../likwid/groups/ivybridge/FLOPS_SP.txt | 33 + collectors/likwid/groups/ivybridge/ICACHE.txt | 33 + collectors/likwid/groups/ivybridge/L2.txt | 38 + .../likwid/groups/ivybridge/L2CACHE.txt | 34 + collectors/likwid/groups/ivybridge/L3.txt | 36 + .../likwid/groups/ivybridge/L3CACHE.txt | 36 + .../likwid/groups/ivybridge/PORT_USAGE.txt | 40 + .../likwid/groups/ivybridge/RECOVERY.txt | 22 + .../likwid/groups/ivybridge/TLB_DATA.txt | 35 + .../likwid/groups/ivybridge/TLB_INSTR.txt | 28 + collectors/likwid/groups/ivybridge/TMA.txt | 48 + collectors/likwid/groups/ivybridge/UOPS.txt | 35 + .../likwid/groups/ivybridge/UOPS_EXEC.txt | 31 + .../likwid/groups/ivybridge/UOPS_ISSUE.txt | 31 + .../likwid/groups/ivybridge/UOPS_RETIRE.txt | 31 + .../likwid/groups/ivybridgeEP/BRANCH.txt | 31 + .../likwid/groups/ivybridgeEP/CACHES.txt | 121 + collectors/likwid/groups/ivybridgeEP/CBOX.txt | 55 + .../likwid/groups/ivybridgeEP/CLOCK.txt | 26 + .../groups/ivybridgeEP/CYCLE_ACTIVITY.txt | 38 + .../groups/ivybridgeEP/CYCLE_STALLS.txt | 45 + collectors/likwid/groups/ivybridgeEP/DATA.txt | 22 + .../likwid/groups/ivybridgeEP/DIVIDE.txt | 24 + .../likwid/groups/ivybridgeEP/ENERGY.txt | 33 + .../likwid/groups/ivybridgeEP/FALSE_SHARE.txt | 32 + .../likwid/groups/ivybridgeEP/FLOPS_AVX.txt | 26 + .../likwid/groups/ivybridgeEP/FLOPS_DP.txt | 33 + .../likwid/groups/ivybridgeEP/FLOPS_SP.txt | 33 + .../likwid/groups/ivybridgeEP/ICACHE.txt | 33 + collectors/likwid/groups/ivybridgeEP/L2.txt | 38 + .../likwid/groups/ivybridgeEP/L2CACHE.txt | 34 + collectors/likwid/groups/ivybridgeEP/L3.txt | 36 + .../likwid/groups/ivybridgeEP/L3CACHE.txt | 36 + collectors/likwid/groups/ivybridgeEP/MEM.txt | 49 + .../likwid/groups/ivybridgeEP/MEM_DP.txt | 75 + .../likwid/groups/ivybridgeEP/MEM_SP.txt | 74 + collectors/likwid/groups/ivybridgeEP/NUMA.txt | 33 + .../likwid/groups/ivybridgeEP/PORT_USAGE.txt | 40 + collectors/likwid/groups/ivybridgeEP/QPI.txt | 52 + .../likwid/groups/ivybridgeEP/RECOVERY.txt | 22 + .../likwid/groups/ivybridgeEP/TLB_DATA.txt | 35 + .../likwid/groups/ivybridgeEP/TLB_INSTR.txt | 28 + collectors/likwid/groups/ivybridgeEP/TMA.txt | 48 + .../likwid/groups/ivybridgeEP/UNCORECLOCK.txt | 96 + collectors/likwid/groups/ivybridgeEP/UOPS.txt | 35 + .../likwid/groups/ivybridgeEP/UOPS_EXEC.txt | 31 + .../likwid/groups/ivybridgeEP/UOPS_ISSUE.txt | 31 + .../likwid/groups/ivybridgeEP/UOPS_RETIRE.txt | 31 + collectors/likwid/groups/k10/BRANCH.txt | 26 + collectors/likwid/groups/k10/CACHE.txt | 34 + collectors/likwid/groups/k10/CPI.txt | 26 + collectors/likwid/groups/k10/FLOPS_DP.txt | 24 + collectors/likwid/groups/k10/FLOPS_SP.txt | 24 + collectors/likwid/groups/k10/FLOPS_X87.txt | 25 + .../likwid/groups/k10/FPU_EXCEPTION.txt | 21 + collectors/likwid/groups/k10/ICACHE.txt | 23 + collectors/likwid/groups/k10/L2.txt | 33 + collectors/likwid/groups/k10/L2CACHE.txt | 32 + collectors/likwid/groups/k10/MEM.txt | 35 + collectors/likwid/groups/k10/NUMA_0_3.txt | 27 + collectors/likwid/groups/k10/NUMA_4_7.txt | 27 + collectors/likwid/groups/k10/TLB.txt | 35 + collectors/likwid/groups/k8/BRANCH.txt | 25 + collectors/likwid/groups/k8/CACHE.txt | 33 + collectors/likwid/groups/k8/CPI.txt | 26 + collectors/likwid/groups/k8/ICACHE.txt | 23 + collectors/likwid/groups/k8/L2.txt | 31 + collectors/likwid/groups/kabini/BRANCH.txt | 26 + collectors/likwid/groups/kabini/CACHE.txt | 32 + collectors/likwid/groups/kabini/CPI.txt | 26 + collectors/likwid/groups/kabini/DATA.txt | 16 + collectors/likwid/groups/kabini/FLOPS_DP.txt | 26 + collectors/likwid/groups/kabini/FLOPS_SP.txt | 26 + .../likwid/groups/kabini/FPU_EXCEPTION.txt | 21 + collectors/likwid/groups/kabini/ICACHE.txt | 23 + collectors/likwid/groups/kabini/L2.txt | 33 + collectors/likwid/groups/kabini/MEM.txt | 20 + collectors/likwid/groups/kabini/NUMA_0_3.txt | 28 + collectors/likwid/groups/kabini/NUMA_4_7.txt | 28 + collectors/likwid/groups/kabini/TLB.txt | 34 + collectors/likwid/groups/knl/BRANCH.txt | 31 + collectors/likwid/groups/knl/CLOCK.txt | 23 + collectors/likwid/groups/knl/DATA.txt | 22 + collectors/likwid/groups/knl/DIVIDE.txt | 24 + collectors/likwid/groups/knl/ENERGY.txt | 33 + collectors/likwid/groups/knl/FLOPS_DP.txt | 34 + collectors/likwid/groups/knl/FLOPS_SP.txt | 34 + .../likwid/groups/knl/FRONTEND_STALLS.txt | 25 + collectors/likwid/groups/knl/HBM.txt | 46 + collectors/likwid/groups/knl/HBM_CACHE.txt | 87 + collectors/likwid/groups/knl/HBM_OFFCORE.txt | 32 + collectors/likwid/groups/knl/ICACHE.txt | 25 + collectors/likwid/groups/knl/L2.txt | 36 + collectors/likwid/groups/knl/L2CACHE.txt | 34 + collectors/likwid/groups/knl/MEM.txt | 47 + collectors/likwid/groups/knl/TLB_DATA.txt | 27 + collectors/likwid/groups/knl/TLB_INSTR.txt | 27 + collectors/likwid/groups/knl/UOPS_STALLS.txt | 25 + collectors/likwid/groups/nehalem/BRANCH.txt | 31 + collectors/likwid/groups/nehalem/CACHE.txt | 36 + collectors/likwid/groups/nehalem/DATA.txt | 22 + collectors/likwid/groups/nehalem/DIVIDE.txt | 24 + collectors/likwid/groups/nehalem/FLOPS_DP.txt | 35 + collectors/likwid/groups/nehalem/FLOPS_SP.txt | 35 + .../likwid/groups/nehalem/FLOPS_X87.txt | 21 + collectors/likwid/groups/nehalem/ICACHE.txt | 25 + collectors/likwid/groups/nehalem/L2.txt | 40 + collectors/likwid/groups/nehalem/L2CACHE.txt | 34 + collectors/likwid/groups/nehalem/L3.txt | 36 + collectors/likwid/groups/nehalem/L3CACHE.txt | 34 + collectors/likwid/groups/nehalem/MEM.txt | 49 + .../likwid/groups/nehalem/SCHEDULER.txt | 25 + collectors/likwid/groups/nehalem/TLB.txt | 30 + collectors/likwid/groups/nehalemEX/BRANCH.txt | 31 + collectors/likwid/groups/nehalemEX/CACHE.txt | 36 + collectors/likwid/groups/nehalemEX/DATA.txt | 22 + collectors/likwid/groups/nehalemEX/DIVIDE.txt | 24 + .../likwid/groups/nehalemEX/FLOPS_DP.txt | 35 + .../likwid/groups/nehalemEX/FLOPS_SP.txt | 35 + .../likwid/groups/nehalemEX/FLOPS_X87.txt | 21 + collectors/likwid/groups/nehalemEX/ICACHE.txt | 25 + collectors/likwid/groups/nehalemEX/L2.txt | 40 + .../likwid/groups/nehalemEX/L2CACHE.txt | 34 + collectors/likwid/groups/nehalemEX/L3.txt | 37 + .../likwid/groups/nehalemEX/L3CACHE.txt | 48 + collectors/likwid/groups/nehalemEX/MEM.txt | 43 + .../likwid/groups/nehalemEX/SCHEDULER.txt | 25 + collectors/likwid/groups/nehalemEX/TLB.txt | 30 + .../likwid/groups/nvidia_gpu_cc_ge_7/DATA.txt | 16 + .../groups/nvidia_gpu_cc_ge_7/FLOPS_DP.txt | 19 + .../groups/nvidia_gpu_cc_ge_7/FLOPS_HP.txt | 19 + .../groups/nvidia_gpu_cc_ge_7/FLOPS_SP.txt | 19 + .../likwid/groups/nvidia_gpu_cc_lt_7/DATA.txt | 20 + .../groups/nvidia_gpu_cc_lt_7/FLOPS_DP.txt | 19 + .../groups/nvidia_gpu_cc_lt_7/FLOPS_SP.txt | 20 + collectors/likwid/groups/pentiumm/BRANCH.txt | 17 + collectors/likwid/groups/pentiumm/CPI.txt | 22 + .../likwid/groups/pentiumm/FLOPS_DP.txt | 20 + .../likwid/groups/pentiumm/FLOPS_SP.txt | 18 + collectors/likwid/groups/pentiumm/L3.txt | 30 + collectors/likwid/groups/phi/CACHE.txt | 22 + .../groups/phi/COMPUTE_TO_DATA_RATIO.txt | 22 + collectors/likwid/groups/phi/CPI.txt | 23 + collectors/likwid/groups/phi/MEM.txt | 18 + collectors/likwid/groups/phi/MEM1.txt | 18 + collectors/likwid/groups/phi/MEM2.txt | 17 + collectors/likwid/groups/phi/MEM3.txt | 17 + collectors/likwid/groups/phi/MEM4.txt | 17 + collectors/likwid/groups/phi/MEM5.txt | 19 + collectors/likwid/groups/phi/MEM6.txt | 17 + collectors/likwid/groups/phi/MEM_READ.txt | 20 + collectors/likwid/groups/phi/MEM_WRITE.txt | 20 + collectors/likwid/groups/phi/PAIRING.txt | 21 + .../likwid/groups/phi/READ_MISS_RATIO.txt | 15 + collectors/likwid/groups/phi/TLB.txt | 23 + collectors/likwid/groups/phi/TLB_L1.txt | 23 + collectors/likwid/groups/phi/TLB_L2.txt | 21 + collectors/likwid/groups/phi/VECTOR.txt | 21 + collectors/likwid/groups/phi/VECTOR2.txt | 20 + .../likwid/groups/phi/VPU_FILL_RATIO_DBL.txt | 18 + collectors/likwid/groups/phi/VPU_PAIRING.txt | 20 + .../likwid/groups/phi/VPU_READ_MISS_RATIO.txt | 16 + .../groups/phi/VPU_WRITE_MISS_RATIO.txt | 16 + .../likwid/groups/phi/WRITE_MISS_RATIO.txt | 15 + collectors/likwid/groups/power8/BRANCH.txt | 30 + collectors/likwid/groups/power8/CPISTACK1.txt | 35 + collectors/likwid/groups/power8/DATA.txt | 23 + collectors/likwid/groups/power8/FLOPS_1_2.txt | 24 + collectors/likwid/groups/power8/FLOPS_4_8.txt | 24 + collectors/likwid/groups/power8/FLOPS_DP.txt | 27 + collectors/likwid/groups/power8/FLOPS_DP2.txt | 27 + collectors/likwid/groups/power8/FLOPS_FMA.txt | 28 + collectors/likwid/groups/power8/FLOPS_SP.txt | 27 + .../likwid/groups/power8/FLOPS_VSU0.txt | 23 + .../likwid/groups/power8/FLOPS_VSU1.txt | 22 + collectors/likwid/groups/power8/FLOPS_VSX.txt | 29 + collectors/likwid/groups/power8/ICACHE.txt | 22 + collectors/likwid/groups/power8/L1.txt | 33 + collectors/likwid/groups/power8/L2.txt | 32 + collectors/likwid/groups/power8/L2CACHE.txt | 40 + collectors/likwid/groups/power8/L3.txt | 31 + collectors/likwid/groups/power8/MEM.txt | 30 + collectors/likwid/groups/power8/NUMA.txt | 29 + collectors/likwid/groups/power8/STALLS1.txt | 33 + collectors/likwid/groups/power8/STALLS2.txt | 32 + collectors/likwid/groups/power8/TLB_DATA.txt | 37 + collectors/likwid/groups/power8/TLB_INSTR.txt | 21 + collectors/likwid/groups/power8/USEFUL.txt | 24 + collectors/likwid/groups/power9/BRANCH.txt | 30 + collectors/likwid/groups/power9/DATA.txt | 23 + collectors/likwid/groups/power9/FLOPS.txt | 25 + collectors/likwid/groups/power9/FLOPS_FMA.txt | 21 + collectors/likwid/groups/power9/FLOPS_VSX.txt | 23 + collectors/likwid/groups/power9/ICACHE.txt | 22 + collectors/likwid/groups/power9/L2CACHE.txt | 33 + collectors/likwid/groups/power9/L2LOAD.txt | 23 + collectors/likwid/groups/power9/L2STORE.txt | 22 + collectors/likwid/groups/power9/L3.txt | 29 + collectors/likwid/groups/power9/MEM.txt | 47 + collectors/likwid/groups/power9/TLB_DATA.txt | 42 + collectors/likwid/groups/power9/TLB_INSTR.txt | 21 + collectors/likwid/groups/power9/USEFUL.txt | 22 + .../likwid/groups/sandybridge/BRANCH.txt | 31 + .../likwid/groups/sandybridge/CLOCK.txt | 30 + .../groups/sandybridge/CYCLE_ACTIVITY.txt | 33 + .../groups/sandybridge/CYCLE_STALLS.txt | 38 + collectors/likwid/groups/sandybridge/DATA.txt | 22 + .../likwid/groups/sandybridge/DIVIDE.txt | 24 + .../likwid/groups/sandybridge/ENERGY.txt | 37 + .../likwid/groups/sandybridge/FALSE_SHARE.txt | 25 + .../likwid/groups/sandybridge/FLOPS_AVX.txt | 26 + .../likwid/groups/sandybridge/FLOPS_DP.txt | 33 + .../likwid/groups/sandybridge/FLOPS_SP.txt | 33 + .../likwid/groups/sandybridge/ICACHE.txt | 33 + collectors/likwid/groups/sandybridge/L2.txt | 38 + .../likwid/groups/sandybridge/L2CACHE.txt | 34 + collectors/likwid/groups/sandybridge/L3.txt | 36 + .../likwid/groups/sandybridge/L3CACHE.txt | 36 + .../likwid/groups/sandybridge/PORT_USAGE.txt | 40 + .../likwid/groups/sandybridge/RECOVERY.txt | 22 + .../likwid/groups/sandybridge/TLB_DATA.txt | 35 + .../likwid/groups/sandybridge/TLB_INSTR.txt | 28 + collectors/likwid/groups/sandybridge/TMA.txt | 48 + collectors/likwid/groups/sandybridge/UOPS.txt | 32 + .../likwid/groups/sandybridge/UOPS_EXEC.txt | 31 + .../likwid/groups/sandybridge/UOPS_ISSUE.txt | 31 + .../likwid/groups/sandybridge/UOPS_RETIRE.txt | 31 + .../likwid/groups/sandybridgeEP/BRANCH.txt | 31 + .../likwid/groups/sandybridgeEP/CACHES.txt | 97 + .../likwid/groups/sandybridgeEP/CLOCK.txt | 30 + .../groups/sandybridgeEP/CYCLE_ACTIVITY.txt | 33 + .../groups/sandybridgeEP/CYCLE_STALLS.txt | 38 + .../likwid/groups/sandybridgeEP/DATA.txt | 22 + .../likwid/groups/sandybridgeEP/DIVIDE.txt | 24 + .../likwid/groups/sandybridgeEP/ENERGY.txt | 33 + .../groups/sandybridgeEP/FALSE_SHARE.txt | 27 + .../likwid/groups/sandybridgeEP/FLOPS_AVX.txt | 26 + .../likwid/groups/sandybridgeEP/FLOPS_DP.txt | 33 + .../likwid/groups/sandybridgeEP/FLOPS_SP.txt | 33 + .../likwid/groups/sandybridgeEP/ICACHE.txt | 33 + collectors/likwid/groups/sandybridgeEP/L2.txt | 38 + .../likwid/groups/sandybridgeEP/L2CACHE.txt | 34 + collectors/likwid/groups/sandybridgeEP/L3.txt | 36 + .../likwid/groups/sandybridgeEP/L3CACHE.txt | 36 + .../likwid/groups/sandybridgeEP/MEM.txt | 40 + .../likwid/groups/sandybridgeEP/MEM_DP.txt | 66 + .../likwid/groups/sandybridgeEP/MEM_SP.txt | 66 + .../likwid/groups/sandybridgeEP/NUMA.txt | 33 + .../groups/sandybridgeEP/PORT_USAGE.txt | 40 + .../likwid/groups/sandybridgeEP/QPI.txt | 35 + .../likwid/groups/sandybridgeEP/RECOVERY.txt | 22 + .../likwid/groups/sandybridgeEP/TLB_DATA.txt | 35 + .../likwid/groups/sandybridgeEP/TLB_INSTR.txt | 28 + .../likwid/groups/sandybridgeEP/TMA.txt | 48 + .../likwid/groups/sandybridgeEP/UOPS.txt | 32 + .../likwid/groups/sandybridgeEP/UOPS_EXEC.txt | 31 + .../groups/sandybridgeEP/UOPS_ISSUE.txt | 31 + .../groups/sandybridgeEP/UOPS_RETIRE.txt | 31 + .../likwid/groups/silvermont/BRANCH.txt | 31 + collectors/likwid/groups/silvermont/CLOCK.txt | 23 + collectors/likwid/groups/silvermont/DATA.txt | 22 + .../likwid/groups/silvermont/DIVIDE.txt | 24 + .../likwid/groups/silvermont/ENERGY.txt | 29 + .../likwid/groups/silvermont/ICACHE.txt | 25 + .../likwid/groups/silvermont/L2CACHE.txt | 34 + collectors/likwid/groups/silvermont/MEM.txt | 37 + .../likwid/groups/silvermont/TLB_DATA.txt | 27 + .../likwid/groups/silvermont/TLB_INSTR.txt | 27 + collectors/likwid/groups/skylake/BRANCH.txt | 31 + collectors/likwid/groups/skylake/CLOCK.txt | 30 + .../likwid/groups/skylake/CYCLE_ACTIVITY.txt | 38 + .../likwid/groups/skylake/CYCLE_STALLS.txt | 45 + collectors/likwid/groups/skylake/DATA.txt | 22 + collectors/likwid/groups/skylake/DIVIDE.txt | 24 + collectors/likwid/groups/skylake/ENERGY.txt | 39 + .../likwid/groups/skylake/FALSE_SHARE.txt | 25 + .../likwid/groups/skylake/FLOPS_AVX.txt | 24 + collectors/likwid/groups/skylake/FLOPS_DP.txt | 31 + collectors/likwid/groups/skylake/FLOPS_SP.txt | 31 + collectors/likwid/groups/skylake/ICACHE.txt | 30 + collectors/likwid/groups/skylake/L2.txt | 38 + collectors/likwid/groups/skylake/L2CACHE.txt | 34 + collectors/likwid/groups/skylake/L3.txt | 36 + collectors/likwid/groups/skylake/L3CACHE.txt | 35 + collectors/likwid/groups/skylake/MEM.txt | 36 + collectors/likwid/groups/skylake/MEM_DP.txt | 59 + collectors/likwid/groups/skylake/MEM_SP.txt | 59 + .../likwid/groups/skylake/PORT_USAGE.txt | 46 + collectors/likwid/groups/skylake/RECOVERY.txt | 22 + collectors/likwid/groups/skylake/TLB_DATA.txt | 35 + .../likwid/groups/skylake/TLB_INSTR.txt | 28 + collectors/likwid/groups/skylake/TMA.txt | 48 + collectors/likwid/groups/skylake/UOPS.txt | 29 + .../likwid/groups/skylake/UOPS_EXEC.txt | 31 + .../likwid/groups/skylake/UOPS_ISSUE.txt | 31 + .../likwid/groups/skylake/UOPS_RETIRE.txt | 31 + collectors/likwid/groups/skylakeX/BRANCH.txt | 31 + collectors/likwid/groups/skylakeX/CACHES.txt | 143 + collectors/likwid/groups/skylakeX/CLOCK.txt | 26 + .../likwid/groups/skylakeX/CYCLE_ACTIVITY.txt | 38 + .../likwid/groups/skylakeX/CYCLE_STALLS.txt | 45 + collectors/likwid/groups/skylakeX/DATA.txt | 22 + collectors/likwid/groups/skylakeX/DIVIDE.txt | 24 + collectors/likwid/groups/skylakeX/ENERGY.txt | 35 + .../likwid/groups/skylakeX/FLOPS_AVX.txt | 25 + .../likwid/groups/skylakeX/FLOPS_DP.txt | 34 + .../likwid/groups/skylakeX/FLOPS_SP.txt | 34 + collectors/likwid/groups/skylakeX/L2.txt | 38 + collectors/likwid/groups/skylakeX/L2CACHE.txt | 34 + collectors/likwid/groups/skylakeX/L3.txt | 48 + collectors/likwid/groups/skylakeX/L3CACHE.txt | 35 + collectors/likwid/groups/skylakeX/MEM.txt | 48 + collectors/likwid/groups/skylakeX/MEM_DP.txt | 70 + collectors/likwid/groups/skylakeX/MEM_SP.txt | 70 + .../likwid/groups/skylakeX/TLB_DATA.txt | 35 + .../likwid/groups/skylakeX/TLB_INSTR.txt | 28 + collectors/likwid/groups/skylakeX/TMA.txt | 48 + .../likwid/groups/skylakeX/UOPS_EXEC.txt | 31 + .../likwid/groups/skylakeX/UOPS_ISSUE.txt | 31 + .../likwid/groups/skylakeX/UOPS_RETIRE.txt | 31 + collectors/likwid/groups/skylakeX/UPI.txt | 42 + collectors/likwid/groups/westmere/BRANCH.txt | 31 + collectors/likwid/groups/westmere/CACHE.txt | 26 + collectors/likwid/groups/westmere/CLOCK.txt | 21 + collectors/likwid/groups/westmere/DATA.txt | 22 + collectors/likwid/groups/westmere/DIVIDE.txt | 24 + .../likwid/groups/westmere/FLOPS_DP.txt | 35 + .../likwid/groups/westmere/FLOPS_SP.txt | 35 + .../likwid/groups/westmere/FLOPS_X87.txt | 21 + collectors/likwid/groups/westmere/ICACHE.txt | 25 + collectors/likwid/groups/westmere/L2.txt | 38 + collectors/likwid/groups/westmere/L2CACHE.txt | 34 + collectors/likwid/groups/westmere/L3.txt | 37 + collectors/likwid/groups/westmere/L3CACHE.txt | 34 + collectors/likwid/groups/westmere/MEM.txt | 50 + collectors/likwid/groups/westmere/MEM_DP.txt | 66 + collectors/likwid/groups/westmere/MEM_SP.txt | 66 + .../likwid/groups/westmere/TLB_DATA.txt | 35 + .../likwid/groups/westmere/TLB_INSTR.txt | 27 + collectors/likwid/groups/westmere/UOPS.txt | 35 + collectors/likwid/groups/westmere/VIEW.txt | 50 + .../likwid/groups/westmereEX/BRANCH.txt | 31 + collectors/likwid/groups/westmereEX/CACHE.txt | 25 + collectors/likwid/groups/westmereEX/DATA.txt | 22 + .../likwid/groups/westmereEX/DIVIDE.txt | 24 + .../likwid/groups/westmereEX/FLOPS_DP.txt | 35 + .../likwid/groups/westmereEX/FLOPS_SP.txt | 35 + .../likwid/groups/westmereEX/FLOPS_X87.txt | 21 + .../likwid/groups/westmereEX/ICACHE.txt | 25 + collectors/likwid/groups/westmereEX/L2.txt | 38 + .../likwid/groups/westmereEX/L2CACHE.txt | 34 + collectors/likwid/groups/westmereEX/L3.txt | 36 + .../likwid/groups/westmereEX/L3CACHE.txt | 52 + collectors/likwid/groups/westmereEX/MEM.txt | 38 + collectors/likwid/groups/westmereEX/NUMA.txt | 33 + .../likwid/groups/westmereEX/TLB_DATA.txt | 35 + .../likwid/groups/westmereEX/TLB_INSTR.txt | 27 + collectors/likwid/groups/westmereEX/UOPS.txt | 32 + collectors/likwid/groups/zen/BRANCH.txt | 32 + collectors/likwid/groups/zen/CACHE.txt | 39 + collectors/likwid/groups/zen/CPI.txt | 30 + collectors/likwid/groups/zen/DATA.txt | 23 + collectors/likwid/groups/zen/DIVIDE.txt | 26 + collectors/likwid/groups/zen/ENERGY.txt | 32 + collectors/likwid/groups/zen/FLOPS_DP.txt | 26 + collectors/likwid/groups/zen/FLOPS_SP.txt | 26 + collectors/likwid/groups/zen/ICACHE.txt | 28 + collectors/likwid/groups/zen/L2.txt | 28 + collectors/likwid/groups/zen/L3.txt | 32 + collectors/likwid/groups/zen/MEM.txt | 32 + collectors/likwid/groups/zen/MEM_DP.txt | 39 + collectors/likwid/groups/zen/MEM_SP.txt | 39 + collectors/likwid/groups/zen/NUMA.txt | 35 + collectors/likwid/groups/zen/TLB.txt | 39 + collectors/likwid/groups/zen2/BRANCH.txt | 32 + collectors/likwid/groups/zen2/CACHE.txt | 39 + collectors/likwid/groups/zen2/CPI.txt | 30 + collectors/likwid/groups/zen2/DATA.txt | 23 + collectors/likwid/groups/zen2/DIVIDE.txt | 25 + collectors/likwid/groups/zen2/ENERGY.txt | 32 + collectors/likwid/groups/zen2/FLOPS_DP.txt | 28 + collectors/likwid/groups/zen2/FLOPS_SP.txt | 28 + collectors/likwid/groups/zen2/ICACHE.txt | 28 + collectors/likwid/groups/zen2/L2.txt | 28 + collectors/likwid/groups/zen2/L3.txt | 32 + collectors/likwid/groups/zen2/MEM.txt | 35 + collectors/likwid/groups/zen2/NUMA.txt | 35 + collectors/likwid/groups/zen2/TLB.txt | 39 + collectors/likwid/groups/zen3/.empty | 1 + collectors/likwid/liblikwid-hwloc.a | Bin 0 -> 600536 bytes collectors/likwid/liblikwid.a | Bin 0 -> 18069980 bytes collectors/likwid/likwid-marker.h | 170 ++ collectors/likwid/likwid.h | 2305 +++++++++++++++++ collectors/likwidMetric.go | 174 ++ 670 files changed, 24926 insertions(+) create mode 100644 collectors/likwid/bstrlib.h create mode 100644 collectors/likwid/groups/CLX/BRANCH.txt create mode 100644 collectors/likwid/groups/CLX/CACHES.txt create mode 100644 collectors/likwid/groups/CLX/CLOCK.txt create mode 100644 collectors/likwid/groups/CLX/CYCLE_ACTIVITY.txt create mode 100644 collectors/likwid/groups/CLX/CYCLE_STALLS.txt create mode 100644 collectors/likwid/groups/CLX/DATA.txt create mode 100644 collectors/likwid/groups/CLX/DIVIDE.txt create mode 100644 collectors/likwid/groups/CLX/ENERGY.txt create mode 100644 collectors/likwid/groups/CLX/FLOPS_AVX.txt create mode 100644 collectors/likwid/groups/CLX/FLOPS_DP.txt create mode 100644 collectors/likwid/groups/CLX/FLOPS_SP.txt create mode 100644 collectors/likwid/groups/CLX/L2.txt create mode 100644 collectors/likwid/groups/CLX/L2CACHE.txt create mode 100644 collectors/likwid/groups/CLX/L3.txt create mode 100644 collectors/likwid/groups/CLX/L3CACHE.txt create mode 100644 collectors/likwid/groups/CLX/MEM.txt create mode 100644 collectors/likwid/groups/CLX/MEM_DP.txt create mode 100644 collectors/likwid/groups/CLX/MEM_SP.txt create mode 100644 collectors/likwid/groups/CLX/PMM.txt create mode 100644 collectors/likwid/groups/CLX/TLB_DATA.txt create mode 100644 collectors/likwid/groups/CLX/TLB_INSTR.txt create mode 100644 collectors/likwid/groups/CLX/TMA.txt create mode 100644 collectors/likwid/groups/CLX/UOPS_EXEC.txt create mode 100644 collectors/likwid/groups/CLX/UOPS_ISSUE.txt create mode 100644 collectors/likwid/groups/CLX/UOPS_RETIRE.txt create mode 100644 collectors/likwid/groups/CLX/UPI.txt create mode 100644 collectors/likwid/groups/ICL/BRANCH.txt create mode 100644 collectors/likwid/groups/ICL/DATA.txt create mode 100644 collectors/likwid/groups/ICL/DIVIDE.txt create mode 100644 collectors/likwid/groups/ICL/ENERGY.txt create mode 100644 collectors/likwid/groups/ICL/FLOPS_AVX.txt create mode 100644 collectors/likwid/groups/ICL/FLOPS_DP.txt create mode 100644 collectors/likwid/groups/ICL/FLOPS_SP.txt create mode 100644 collectors/likwid/groups/ICX/BRANCH.txt create mode 100644 collectors/likwid/groups/ICX/DATA.txt create mode 100644 collectors/likwid/groups/ICX/DIVIDE.txt create mode 100644 collectors/likwid/groups/ICX/FLOPS_AVX.txt create mode 100644 collectors/likwid/groups/ICX/FLOPS_DP.txt create mode 100644 collectors/likwid/groups/ICX/FLOPS_SP.txt create mode 100644 collectors/likwid/groups/ICX/L2.txt create mode 100644 collectors/likwid/groups/TGL/BRANCH.txt create mode 100644 collectors/likwid/groups/TGL/DATA.txt create mode 100644 collectors/likwid/groups/TGL/DIVIDE.txt create mode 100644 collectors/likwid/groups/TGL/ENERGY.txt create mode 100644 collectors/likwid/groups/TGL/FLOPS_AVX.txt create mode 100644 collectors/likwid/groups/TGL/FLOPS_DP.txt create mode 100644 collectors/likwid/groups/TGL/FLOPS_SP.txt create mode 100644 collectors/likwid/groups/arm64fx/BRANCH.txt create mode 100644 collectors/likwid/groups/arm64fx/DATA.txt create mode 100644 collectors/likwid/groups/arm64fx/FLOPS_DP.txt create mode 100644 collectors/likwid/groups/arm64fx/FLOPS_HP.txt create mode 100644 collectors/likwid/groups/arm64fx/FLOPS_SP.txt create mode 100644 collectors/likwid/groups/arm64fx/FP_PIPE.txt create mode 100644 collectors/likwid/groups/arm64fx/ICACHE.txt create mode 100644 collectors/likwid/groups/arm64fx/L2.txt create mode 100644 collectors/likwid/groups/arm64fx/MEM.txt create mode 100644 collectors/likwid/groups/arm64fx/MEM_DP.txt create mode 100644 collectors/likwid/groups/arm64fx/MEM_HP.txt create mode 100644 collectors/likwid/groups/arm64fx/MEM_SP.txt create mode 100644 collectors/likwid/groups/arm64fx/PCI.txt create mode 100644 collectors/likwid/groups/arm64fx/TOFU.txt create mode 100644 collectors/likwid/groups/arm8/BRANCH.txt create mode 100644 collectors/likwid/groups/arm8/DATA.txt create mode 100644 collectors/likwid/groups/arm8/ICACHE.txt create mode 100644 collectors/likwid/groups/arm8/L2.txt create mode 100644 collectors/likwid/groups/arm8/MEM.txt create mode 100644 collectors/likwid/groups/arm8_n1/BRANCH.txt create mode 100644 collectors/likwid/groups/arm8_n1/CLOCK.txt create mode 100644 collectors/likwid/groups/arm8_n1/DATA.txt create mode 100644 collectors/likwid/groups/arm8_n1/ICACHE.txt create mode 100644 collectors/likwid/groups/arm8_n1/L2.txt create mode 100644 collectors/likwid/groups/arm8_n1/L3.txt create mode 100644 collectors/likwid/groups/arm8_n1/MEM.txt create mode 100644 collectors/likwid/groups/arm8_n1/TLB.txt create mode 100644 collectors/likwid/groups/arm8_tx2/BRANCH.txt create mode 100644 collectors/likwid/groups/arm8_tx2/DATA.txt create mode 100644 collectors/likwid/groups/arm8_tx2/FLOPS_DP.txt create mode 100644 collectors/likwid/groups/arm8_tx2/FLOPS_SP.txt create mode 100644 collectors/likwid/groups/arm8_tx2/ICACHE.txt create mode 100644 collectors/likwid/groups/arm8_tx2/L2.txt create mode 100644 collectors/likwid/groups/arm8_tx2/L2CACHE.txt create mode 100644 collectors/likwid/groups/arm8_tx2/L3.txt create mode 100644 collectors/likwid/groups/arm8_tx2/MEM.txt create mode 100644 collectors/likwid/groups/arm8_tx2/SPEC.txt create mode 100644 collectors/likwid/groups/arm8_tx2/TLB_DATA.txt create mode 100644 collectors/likwid/groups/arm8_tx2/TLB_INSTR.txt create mode 100644 collectors/likwid/groups/atom/BRANCH.txt create mode 100644 collectors/likwid/groups/atom/DATA.txt create mode 100644 collectors/likwid/groups/atom/FLOPS_DP.txt create mode 100644 collectors/likwid/groups/atom/FLOPS_SP.txt create mode 100644 collectors/likwid/groups/atom/FLOPS_X87.txt create mode 100644 collectors/likwid/groups/atom/MEM.txt create mode 100644 collectors/likwid/groups/atom/TLB.txt create mode 100644 collectors/likwid/groups/broadwell/BRANCH.txt create mode 100644 collectors/likwid/groups/broadwell/CLOCK.txt create mode 100644 collectors/likwid/groups/broadwell/CYCLE_ACTIVITY.txt create mode 100644 collectors/likwid/groups/broadwell/CYCLE_STALLS.txt create mode 100644 collectors/likwid/groups/broadwell/DATA.txt create mode 100644 collectors/likwid/groups/broadwell/DIVIDE.txt create mode 100644 collectors/likwid/groups/broadwell/ENERGY.txt create mode 100644 collectors/likwid/groups/broadwell/FALSE_SHARE.txt create mode 100644 collectors/likwid/groups/broadwell/FLOPS_AVX.txt create mode 100644 collectors/likwid/groups/broadwell/FLOPS_DP.txt create mode 100644 collectors/likwid/groups/broadwell/FLOPS_SP.txt create mode 100644 collectors/likwid/groups/broadwell/ICACHE.txt create mode 100644 collectors/likwid/groups/broadwell/L2.txt create mode 100644 collectors/likwid/groups/broadwell/L2CACHE.txt create mode 100644 collectors/likwid/groups/broadwell/L3.txt create mode 100644 collectors/likwid/groups/broadwell/L3CACHE.txt create mode 100644 collectors/likwid/groups/broadwell/PORT_USAGE.txt create mode 100644 collectors/likwid/groups/broadwell/RECOVERY.txt create mode 100644 collectors/likwid/groups/broadwell/TLB_DATA.txt create mode 100644 collectors/likwid/groups/broadwell/TLB_INSTR.txt create mode 100644 collectors/likwid/groups/broadwell/TMA.txt create mode 100644 collectors/likwid/groups/broadwell/UOPS.txt create mode 100644 collectors/likwid/groups/broadwellD/BRANCH.txt create mode 100644 collectors/likwid/groups/broadwellD/CACHES.txt create mode 100644 collectors/likwid/groups/broadwellD/CLOCK.txt create mode 100644 collectors/likwid/groups/broadwellD/CYCLE_ACTIVITY.txt create mode 100644 collectors/likwid/groups/broadwellD/CYCLE_STALLS.txt create mode 100644 collectors/likwid/groups/broadwellD/DATA.txt create mode 100644 collectors/likwid/groups/broadwellD/DIVIDE.txt create mode 100644 collectors/likwid/groups/broadwellD/ENERGY.txt create mode 100644 collectors/likwid/groups/broadwellD/FALSE_SHARE.txt create mode 100644 collectors/likwid/groups/broadwellD/FLOPS_AVX.txt create mode 100644 collectors/likwid/groups/broadwellD/FLOPS_DP.txt create mode 100644 collectors/likwid/groups/broadwellD/FLOPS_SP.txt create mode 100644 collectors/likwid/groups/broadwellD/HA.txt create mode 100644 collectors/likwid/groups/broadwellD/ICACHE.txt create mode 100644 collectors/likwid/groups/broadwellD/L2.txt create mode 100644 collectors/likwid/groups/broadwellD/L2CACHE.txt create mode 100644 collectors/likwid/groups/broadwellD/L3.txt create mode 100644 collectors/likwid/groups/broadwellD/L3CACHE.txt create mode 100644 collectors/likwid/groups/broadwellD/MEM.txt create mode 100644 collectors/likwid/groups/broadwellD/MEM_DP.txt create mode 100644 collectors/likwid/groups/broadwellD/MEM_SP.txt create mode 100644 collectors/likwid/groups/broadwellD/PORT_USAGE.txt create mode 100644 collectors/likwid/groups/broadwellD/RECOVERY.txt create mode 100644 collectors/likwid/groups/broadwellD/TLB_DATA.txt create mode 100644 collectors/likwid/groups/broadwellD/TLB_INSTR.txt create mode 100644 collectors/likwid/groups/broadwellD/TMA.txt create mode 100644 collectors/likwid/groups/broadwellD/UOPS.txt create mode 100644 collectors/likwid/groups/broadwellEP/BRANCH.txt create mode 100644 collectors/likwid/groups/broadwellEP/CACHES.txt create mode 100644 collectors/likwid/groups/broadwellEP/CLOCK.txt create mode 100644 collectors/likwid/groups/broadwellEP/CYCLE_ACTIVITY.txt create mode 100644 collectors/likwid/groups/broadwellEP/CYCLE_STALLS.txt create mode 100644 collectors/likwid/groups/broadwellEP/DATA.txt create mode 100644 collectors/likwid/groups/broadwellEP/DIVIDE.txt create mode 100644 collectors/likwid/groups/broadwellEP/ENERGY.txt create mode 100644 collectors/likwid/groups/broadwellEP/FALSE_SHARE.txt create mode 100644 collectors/likwid/groups/broadwellEP/FLOPS_AVX.txt create mode 100644 collectors/likwid/groups/broadwellEP/FLOPS_DP.txt create mode 100644 collectors/likwid/groups/broadwellEP/FLOPS_SP.txt create mode 100644 collectors/likwid/groups/broadwellEP/HA.txt create mode 100644 collectors/likwid/groups/broadwellEP/ICACHE.txt create mode 100644 collectors/likwid/groups/broadwellEP/L2.txt create mode 100644 collectors/likwid/groups/broadwellEP/L2CACHE.txt create mode 100644 collectors/likwid/groups/broadwellEP/L3.txt create mode 100644 collectors/likwid/groups/broadwellEP/L3CACHE.txt create mode 100644 collectors/likwid/groups/broadwellEP/MEM.txt create mode 100644 collectors/likwid/groups/broadwellEP/MEM_DP.txt create mode 100644 collectors/likwid/groups/broadwellEP/MEM_SP.txt create mode 100644 collectors/likwid/groups/broadwellEP/NUMA.txt create mode 100644 collectors/likwid/groups/broadwellEP/PORT_USAGE.txt create mode 100644 collectors/likwid/groups/broadwellEP/QPI.txt create mode 100644 collectors/likwid/groups/broadwellEP/TLB_DATA.txt create mode 100644 collectors/likwid/groups/broadwellEP/TLB_INSTR.txt create mode 100644 collectors/likwid/groups/broadwellEP/TMA.txt create mode 100644 collectors/likwid/groups/broadwellEP/UOPS.txt create mode 100644 collectors/likwid/groups/core2/BRANCH.txt create mode 100644 collectors/likwid/groups/core2/CACHE.txt create mode 100644 collectors/likwid/groups/core2/CLOCK.txt create mode 100644 collectors/likwid/groups/core2/DATA.txt create mode 100644 collectors/likwid/groups/core2/DIVIDE.txt create mode 100644 collectors/likwid/groups/core2/FLOPS_DP.txt create mode 100644 collectors/likwid/groups/core2/FLOPS_SP.txt create mode 100644 collectors/likwid/groups/core2/FLOPS_X87.txt create mode 100644 collectors/likwid/groups/core2/L2.txt create mode 100644 collectors/likwid/groups/core2/L2CACHE.txt create mode 100644 collectors/likwid/groups/core2/MEM.txt create mode 100644 collectors/likwid/groups/core2/TLB.txt create mode 100644 collectors/likwid/groups/core2/UOPS.txt create mode 100644 collectors/likwid/groups/core2/UOPS_RETIRE.txt create mode 100644 collectors/likwid/groups/goldmont/BRANCH.txt create mode 100644 collectors/likwid/groups/goldmont/CLOCK.txt create mode 100644 collectors/likwid/groups/goldmont/DATA.txt create mode 100644 collectors/likwid/groups/goldmont/DIVIDE.txt create mode 100644 collectors/likwid/groups/goldmont/ENERGY.txt create mode 100644 collectors/likwid/groups/goldmont/ICACHE.txt create mode 100644 collectors/likwid/groups/goldmont/L2CACHE.txt create mode 100644 collectors/likwid/groups/goldmont/TLB_DATA.txt create mode 100644 collectors/likwid/groups/goldmont/TLB_INSTR.txt create mode 100644 collectors/likwid/groups/haswell/BRANCH.txt create mode 100644 collectors/likwid/groups/haswell/CACHES.txt create mode 100644 collectors/likwid/groups/haswell/CLOCK.txt create mode 100644 collectors/likwid/groups/haswell/CYCLE_ACTIVITY.txt create mode 100644 collectors/likwid/groups/haswell/CYCLE_STALLS.txt create mode 100644 collectors/likwid/groups/haswell/DATA.txt create mode 100644 collectors/likwid/groups/haswell/DIVIDE.txt create mode 100644 collectors/likwid/groups/haswell/ENERGY.txt create mode 100644 collectors/likwid/groups/haswell/FALSE_SHARE.txt create mode 100644 collectors/likwid/groups/haswell/FLOPS_AVX.txt create mode 100644 collectors/likwid/groups/haswell/ICACHE.txt create mode 100644 collectors/likwid/groups/haswell/L2.txt create mode 100644 collectors/likwid/groups/haswell/L2CACHE.txt create mode 100644 collectors/likwid/groups/haswell/L3.txt create mode 100644 collectors/likwid/groups/haswell/L3CACHE.txt create mode 100644 collectors/likwid/groups/haswell/MEM.txt create mode 100644 collectors/likwid/groups/haswell/PORT_USAGE.txt create mode 100644 collectors/likwid/groups/haswell/RECOVERY.txt create mode 100644 collectors/likwid/groups/haswell/TLB_DATA.txt create mode 100644 collectors/likwid/groups/haswell/TLB_INSTR.txt create mode 100644 collectors/likwid/groups/haswell/TMA.txt create mode 100644 collectors/likwid/groups/haswell/UOPS.txt create mode 100644 collectors/likwid/groups/haswell/UOPS_EXEC.txt create mode 100644 collectors/likwid/groups/haswell/UOPS_ISSUE.txt create mode 100644 collectors/likwid/groups/haswell/UOPS_RETIRE.txt create mode 100644 collectors/likwid/groups/haswellEP/BRANCH.txt create mode 100644 collectors/likwid/groups/haswellEP/CACHES.txt create mode 100644 collectors/likwid/groups/haswellEP/CBOX.txt create mode 100644 collectors/likwid/groups/haswellEP/CLOCK.txt create mode 100644 collectors/likwid/groups/haswellEP/CYCLE_ACTIVITY.txt create mode 100644 collectors/likwid/groups/haswellEP/CYCLE_STALLS.txt create mode 100644 collectors/likwid/groups/haswellEP/DATA.txt create mode 100644 collectors/likwid/groups/haswellEP/DIVIDE.txt create mode 100644 collectors/likwid/groups/haswellEP/ENERGY.txt create mode 100644 collectors/likwid/groups/haswellEP/FALSE_SHARE.txt create mode 100644 collectors/likwid/groups/haswellEP/FLOPS_AVX.txt create mode 100644 collectors/likwid/groups/haswellEP/HA.txt create mode 100644 collectors/likwid/groups/haswellEP/ICACHE.txt create mode 100644 collectors/likwid/groups/haswellEP/L2.txt create mode 100644 collectors/likwid/groups/haswellEP/L2CACHE.txt create mode 100644 collectors/likwid/groups/haswellEP/L3.txt create mode 100644 collectors/likwid/groups/haswellEP/L3CACHE.txt create mode 100644 collectors/likwid/groups/haswellEP/MEM.txt create mode 100644 collectors/likwid/groups/haswellEP/NUMA.txt create mode 100644 collectors/likwid/groups/haswellEP/PORT_USAGE.txt create mode 100644 collectors/likwid/groups/haswellEP/QPI.txt create mode 100644 collectors/likwid/groups/haswellEP/RECOVERY.txt create mode 100644 collectors/likwid/groups/haswellEP/SBOX.txt create mode 100644 collectors/likwid/groups/haswellEP/TLB_DATA.txt create mode 100644 collectors/likwid/groups/haswellEP/TLB_INSTR.txt create mode 100644 collectors/likwid/groups/haswellEP/TMA.txt create mode 100644 collectors/likwid/groups/haswellEP/UOPS.txt create mode 100644 collectors/likwid/groups/haswellEP/UOPS_EXEC.txt create mode 100644 collectors/likwid/groups/haswellEP/UOPS_ISSUE.txt create mode 100644 collectors/likwid/groups/haswellEP/UOPS_RETIRE.txt create mode 100644 collectors/likwid/groups/interlagos/BRANCH.txt create mode 100644 collectors/likwid/groups/interlagos/CACHE.txt create mode 100644 collectors/likwid/groups/interlagos/CPI.txt create mode 100644 collectors/likwid/groups/interlagos/DATA.txt create mode 100644 collectors/likwid/groups/interlagos/FLOPS_DP.txt create mode 100644 collectors/likwid/groups/interlagos/FLOPS_SP.txt create mode 100644 collectors/likwid/groups/interlagos/FPU_EXCEPTION.txt create mode 100644 collectors/likwid/groups/interlagos/ICACHE.txt create mode 100644 collectors/likwid/groups/interlagos/L2.txt create mode 100644 collectors/likwid/groups/interlagos/L2CACHE.txt create mode 100644 collectors/likwid/groups/interlagos/L3.txt create mode 100644 collectors/likwid/groups/interlagos/L3CACHE.txt create mode 100644 collectors/likwid/groups/interlagos/LINKS.txt create mode 100644 collectors/likwid/groups/interlagos/MEM.txt create mode 100644 collectors/likwid/groups/interlagos/NUMA.txt create mode 100644 collectors/likwid/groups/interlagos/NUMA_0_3.txt create mode 100644 collectors/likwid/groups/interlagos/NUMA_4_7.txt create mode 100644 collectors/likwid/groups/ivybridge/BRANCH.txt create mode 100644 collectors/likwid/groups/ivybridge/CLOCK.txt create mode 100644 collectors/likwid/groups/ivybridge/CYCLE_ACTIVITY.txt create mode 100644 collectors/likwid/groups/ivybridge/CYCLE_STALLS.txt create mode 100644 collectors/likwid/groups/ivybridge/DATA.txt create mode 100644 collectors/likwid/groups/ivybridge/DIVIDE.txt create mode 100644 collectors/likwid/groups/ivybridge/ENERGY.txt create mode 100644 collectors/likwid/groups/ivybridge/FALSE_SHARE.txt create mode 100644 collectors/likwid/groups/ivybridge/FLOPS_AVX.txt create mode 100644 collectors/likwid/groups/ivybridge/FLOPS_DP.txt create mode 100644 collectors/likwid/groups/ivybridge/FLOPS_SP.txt create mode 100644 collectors/likwid/groups/ivybridge/ICACHE.txt create mode 100644 collectors/likwid/groups/ivybridge/L2.txt create mode 100644 collectors/likwid/groups/ivybridge/L2CACHE.txt create mode 100644 collectors/likwid/groups/ivybridge/L3.txt create mode 100644 collectors/likwid/groups/ivybridge/L3CACHE.txt create mode 100644 collectors/likwid/groups/ivybridge/PORT_USAGE.txt create mode 100644 collectors/likwid/groups/ivybridge/RECOVERY.txt create mode 100644 collectors/likwid/groups/ivybridge/TLB_DATA.txt create mode 100644 collectors/likwid/groups/ivybridge/TLB_INSTR.txt create mode 100644 collectors/likwid/groups/ivybridge/TMA.txt create mode 100644 collectors/likwid/groups/ivybridge/UOPS.txt create mode 100644 collectors/likwid/groups/ivybridge/UOPS_EXEC.txt create mode 100644 collectors/likwid/groups/ivybridge/UOPS_ISSUE.txt create mode 100644 collectors/likwid/groups/ivybridge/UOPS_RETIRE.txt create mode 100644 collectors/likwid/groups/ivybridgeEP/BRANCH.txt create mode 100644 collectors/likwid/groups/ivybridgeEP/CACHES.txt create mode 100644 collectors/likwid/groups/ivybridgeEP/CBOX.txt create mode 100644 collectors/likwid/groups/ivybridgeEP/CLOCK.txt create mode 100644 collectors/likwid/groups/ivybridgeEP/CYCLE_ACTIVITY.txt create mode 100644 collectors/likwid/groups/ivybridgeEP/CYCLE_STALLS.txt create mode 100644 collectors/likwid/groups/ivybridgeEP/DATA.txt create mode 100644 collectors/likwid/groups/ivybridgeEP/DIVIDE.txt create mode 100644 collectors/likwid/groups/ivybridgeEP/ENERGY.txt create mode 100644 collectors/likwid/groups/ivybridgeEP/FALSE_SHARE.txt create mode 100644 collectors/likwid/groups/ivybridgeEP/FLOPS_AVX.txt create mode 100644 collectors/likwid/groups/ivybridgeEP/FLOPS_DP.txt create mode 100644 collectors/likwid/groups/ivybridgeEP/FLOPS_SP.txt create mode 100644 collectors/likwid/groups/ivybridgeEP/ICACHE.txt create mode 100644 collectors/likwid/groups/ivybridgeEP/L2.txt create mode 100644 collectors/likwid/groups/ivybridgeEP/L2CACHE.txt create mode 100644 collectors/likwid/groups/ivybridgeEP/L3.txt create mode 100644 collectors/likwid/groups/ivybridgeEP/L3CACHE.txt create mode 100644 collectors/likwid/groups/ivybridgeEP/MEM.txt create mode 100644 collectors/likwid/groups/ivybridgeEP/MEM_DP.txt create mode 100644 collectors/likwid/groups/ivybridgeEP/MEM_SP.txt create mode 100644 collectors/likwid/groups/ivybridgeEP/NUMA.txt create mode 100644 collectors/likwid/groups/ivybridgeEP/PORT_USAGE.txt create mode 100644 collectors/likwid/groups/ivybridgeEP/QPI.txt create mode 100644 collectors/likwid/groups/ivybridgeEP/RECOVERY.txt create mode 100644 collectors/likwid/groups/ivybridgeEP/TLB_DATA.txt create mode 100644 collectors/likwid/groups/ivybridgeEP/TLB_INSTR.txt create mode 100644 collectors/likwid/groups/ivybridgeEP/TMA.txt create mode 100644 collectors/likwid/groups/ivybridgeEP/UNCORECLOCK.txt create mode 100644 collectors/likwid/groups/ivybridgeEP/UOPS.txt create mode 100644 collectors/likwid/groups/ivybridgeEP/UOPS_EXEC.txt create mode 100644 collectors/likwid/groups/ivybridgeEP/UOPS_ISSUE.txt create mode 100644 collectors/likwid/groups/ivybridgeEP/UOPS_RETIRE.txt create mode 100644 collectors/likwid/groups/k10/BRANCH.txt create mode 100644 collectors/likwid/groups/k10/CACHE.txt create mode 100644 collectors/likwid/groups/k10/CPI.txt create mode 100644 collectors/likwid/groups/k10/FLOPS_DP.txt create mode 100644 collectors/likwid/groups/k10/FLOPS_SP.txt create mode 100644 collectors/likwid/groups/k10/FLOPS_X87.txt create mode 100644 collectors/likwid/groups/k10/FPU_EXCEPTION.txt create mode 100644 collectors/likwid/groups/k10/ICACHE.txt create mode 100644 collectors/likwid/groups/k10/L2.txt create mode 100644 collectors/likwid/groups/k10/L2CACHE.txt create mode 100644 collectors/likwid/groups/k10/MEM.txt create mode 100644 collectors/likwid/groups/k10/NUMA_0_3.txt create mode 100644 collectors/likwid/groups/k10/NUMA_4_7.txt create mode 100644 collectors/likwid/groups/k10/TLB.txt create mode 100644 collectors/likwid/groups/k8/BRANCH.txt create mode 100644 collectors/likwid/groups/k8/CACHE.txt create mode 100644 collectors/likwid/groups/k8/CPI.txt create mode 100644 collectors/likwid/groups/k8/ICACHE.txt create mode 100644 collectors/likwid/groups/k8/L2.txt create mode 100644 collectors/likwid/groups/kabini/BRANCH.txt create mode 100644 collectors/likwid/groups/kabini/CACHE.txt create mode 100644 collectors/likwid/groups/kabini/CPI.txt create mode 100644 collectors/likwid/groups/kabini/DATA.txt create mode 100644 collectors/likwid/groups/kabini/FLOPS_DP.txt create mode 100644 collectors/likwid/groups/kabini/FLOPS_SP.txt create mode 100644 collectors/likwid/groups/kabini/FPU_EXCEPTION.txt create mode 100644 collectors/likwid/groups/kabini/ICACHE.txt create mode 100644 collectors/likwid/groups/kabini/L2.txt create mode 100644 collectors/likwid/groups/kabini/MEM.txt create mode 100644 collectors/likwid/groups/kabini/NUMA_0_3.txt create mode 100644 collectors/likwid/groups/kabini/NUMA_4_7.txt create mode 100644 collectors/likwid/groups/kabini/TLB.txt create mode 100644 collectors/likwid/groups/knl/BRANCH.txt create mode 100644 collectors/likwid/groups/knl/CLOCK.txt create mode 100644 collectors/likwid/groups/knl/DATA.txt create mode 100644 collectors/likwid/groups/knl/DIVIDE.txt create mode 100644 collectors/likwid/groups/knl/ENERGY.txt create mode 100644 collectors/likwid/groups/knl/FLOPS_DP.txt create mode 100644 collectors/likwid/groups/knl/FLOPS_SP.txt create mode 100644 collectors/likwid/groups/knl/FRONTEND_STALLS.txt create mode 100644 collectors/likwid/groups/knl/HBM.txt create mode 100644 collectors/likwid/groups/knl/HBM_CACHE.txt create mode 100644 collectors/likwid/groups/knl/HBM_OFFCORE.txt create mode 100644 collectors/likwid/groups/knl/ICACHE.txt create mode 100644 collectors/likwid/groups/knl/L2.txt create mode 100644 collectors/likwid/groups/knl/L2CACHE.txt create mode 100644 collectors/likwid/groups/knl/MEM.txt create mode 100644 collectors/likwid/groups/knl/TLB_DATA.txt create mode 100644 collectors/likwid/groups/knl/TLB_INSTR.txt create mode 100644 collectors/likwid/groups/knl/UOPS_STALLS.txt create mode 100644 collectors/likwid/groups/nehalem/BRANCH.txt create mode 100644 collectors/likwid/groups/nehalem/CACHE.txt create mode 100644 collectors/likwid/groups/nehalem/DATA.txt create mode 100644 collectors/likwid/groups/nehalem/DIVIDE.txt create mode 100644 collectors/likwid/groups/nehalem/FLOPS_DP.txt create mode 100644 collectors/likwid/groups/nehalem/FLOPS_SP.txt create mode 100644 collectors/likwid/groups/nehalem/FLOPS_X87.txt create mode 100644 collectors/likwid/groups/nehalem/ICACHE.txt create mode 100644 collectors/likwid/groups/nehalem/L2.txt create mode 100644 collectors/likwid/groups/nehalem/L2CACHE.txt create mode 100644 collectors/likwid/groups/nehalem/L3.txt create mode 100644 collectors/likwid/groups/nehalem/L3CACHE.txt create mode 100644 collectors/likwid/groups/nehalem/MEM.txt create mode 100644 collectors/likwid/groups/nehalem/SCHEDULER.txt create mode 100644 collectors/likwid/groups/nehalem/TLB.txt create mode 100644 collectors/likwid/groups/nehalemEX/BRANCH.txt create mode 100644 collectors/likwid/groups/nehalemEX/CACHE.txt create mode 100644 collectors/likwid/groups/nehalemEX/DATA.txt create mode 100644 collectors/likwid/groups/nehalemEX/DIVIDE.txt create mode 100644 collectors/likwid/groups/nehalemEX/FLOPS_DP.txt create mode 100644 collectors/likwid/groups/nehalemEX/FLOPS_SP.txt create mode 100644 collectors/likwid/groups/nehalemEX/FLOPS_X87.txt create mode 100644 collectors/likwid/groups/nehalemEX/ICACHE.txt create mode 100644 collectors/likwid/groups/nehalemEX/L2.txt create mode 100644 collectors/likwid/groups/nehalemEX/L2CACHE.txt create mode 100644 collectors/likwid/groups/nehalemEX/L3.txt create mode 100644 collectors/likwid/groups/nehalemEX/L3CACHE.txt create mode 100644 collectors/likwid/groups/nehalemEX/MEM.txt create mode 100644 collectors/likwid/groups/nehalemEX/SCHEDULER.txt create mode 100644 collectors/likwid/groups/nehalemEX/TLB.txt create mode 100644 collectors/likwid/groups/nvidia_gpu_cc_ge_7/DATA.txt create mode 100644 collectors/likwid/groups/nvidia_gpu_cc_ge_7/FLOPS_DP.txt create mode 100644 collectors/likwid/groups/nvidia_gpu_cc_ge_7/FLOPS_HP.txt create mode 100644 collectors/likwid/groups/nvidia_gpu_cc_ge_7/FLOPS_SP.txt create mode 100644 collectors/likwid/groups/nvidia_gpu_cc_lt_7/DATA.txt create mode 100644 collectors/likwid/groups/nvidia_gpu_cc_lt_7/FLOPS_DP.txt create mode 100644 collectors/likwid/groups/nvidia_gpu_cc_lt_7/FLOPS_SP.txt create mode 100644 collectors/likwid/groups/pentiumm/BRANCH.txt create mode 100644 collectors/likwid/groups/pentiumm/CPI.txt create mode 100644 collectors/likwid/groups/pentiumm/FLOPS_DP.txt create mode 100644 collectors/likwid/groups/pentiumm/FLOPS_SP.txt create mode 100644 collectors/likwid/groups/pentiumm/L3.txt create mode 100644 collectors/likwid/groups/phi/CACHE.txt create mode 100644 collectors/likwid/groups/phi/COMPUTE_TO_DATA_RATIO.txt create mode 100644 collectors/likwid/groups/phi/CPI.txt create mode 100644 collectors/likwid/groups/phi/MEM.txt create mode 100644 collectors/likwid/groups/phi/MEM1.txt create mode 100644 collectors/likwid/groups/phi/MEM2.txt create mode 100644 collectors/likwid/groups/phi/MEM3.txt create mode 100644 collectors/likwid/groups/phi/MEM4.txt create mode 100644 collectors/likwid/groups/phi/MEM5.txt create mode 100644 collectors/likwid/groups/phi/MEM6.txt create mode 100644 collectors/likwid/groups/phi/MEM_READ.txt create mode 100644 collectors/likwid/groups/phi/MEM_WRITE.txt create mode 100644 collectors/likwid/groups/phi/PAIRING.txt create mode 100644 collectors/likwid/groups/phi/READ_MISS_RATIO.txt create mode 100644 collectors/likwid/groups/phi/TLB.txt create mode 100644 collectors/likwid/groups/phi/TLB_L1.txt create mode 100644 collectors/likwid/groups/phi/TLB_L2.txt create mode 100644 collectors/likwid/groups/phi/VECTOR.txt create mode 100644 collectors/likwid/groups/phi/VECTOR2.txt create mode 100644 collectors/likwid/groups/phi/VPU_FILL_RATIO_DBL.txt create mode 100644 collectors/likwid/groups/phi/VPU_PAIRING.txt create mode 100644 collectors/likwid/groups/phi/VPU_READ_MISS_RATIO.txt create mode 100644 collectors/likwid/groups/phi/VPU_WRITE_MISS_RATIO.txt create mode 100644 collectors/likwid/groups/phi/WRITE_MISS_RATIO.txt create mode 100644 collectors/likwid/groups/power8/BRANCH.txt create mode 100644 collectors/likwid/groups/power8/CPISTACK1.txt create mode 100644 collectors/likwid/groups/power8/DATA.txt create mode 100644 collectors/likwid/groups/power8/FLOPS_1_2.txt create mode 100644 collectors/likwid/groups/power8/FLOPS_4_8.txt create mode 100644 collectors/likwid/groups/power8/FLOPS_DP.txt create mode 100644 collectors/likwid/groups/power8/FLOPS_DP2.txt create mode 100644 collectors/likwid/groups/power8/FLOPS_FMA.txt create mode 100644 collectors/likwid/groups/power8/FLOPS_SP.txt create mode 100644 collectors/likwid/groups/power8/FLOPS_VSU0.txt create mode 100644 collectors/likwid/groups/power8/FLOPS_VSU1.txt create mode 100644 collectors/likwid/groups/power8/FLOPS_VSX.txt create mode 100644 collectors/likwid/groups/power8/ICACHE.txt create mode 100644 collectors/likwid/groups/power8/L1.txt create mode 100644 collectors/likwid/groups/power8/L2.txt create mode 100644 collectors/likwid/groups/power8/L2CACHE.txt create mode 100644 collectors/likwid/groups/power8/L3.txt create mode 100644 collectors/likwid/groups/power8/MEM.txt create mode 100644 collectors/likwid/groups/power8/NUMA.txt create mode 100644 collectors/likwid/groups/power8/STALLS1.txt create mode 100644 collectors/likwid/groups/power8/STALLS2.txt create mode 100644 collectors/likwid/groups/power8/TLB_DATA.txt create mode 100644 collectors/likwid/groups/power8/TLB_INSTR.txt create mode 100644 collectors/likwid/groups/power8/USEFUL.txt create mode 100644 collectors/likwid/groups/power9/BRANCH.txt create mode 100644 collectors/likwid/groups/power9/DATA.txt create mode 100644 collectors/likwid/groups/power9/FLOPS.txt create mode 100644 collectors/likwid/groups/power9/FLOPS_FMA.txt create mode 100644 collectors/likwid/groups/power9/FLOPS_VSX.txt create mode 100644 collectors/likwid/groups/power9/ICACHE.txt create mode 100644 collectors/likwid/groups/power9/L2CACHE.txt create mode 100644 collectors/likwid/groups/power9/L2LOAD.txt create mode 100644 collectors/likwid/groups/power9/L2STORE.txt create mode 100644 collectors/likwid/groups/power9/L3.txt create mode 100644 collectors/likwid/groups/power9/MEM.txt create mode 100644 collectors/likwid/groups/power9/TLB_DATA.txt create mode 100644 collectors/likwid/groups/power9/TLB_INSTR.txt create mode 100644 collectors/likwid/groups/power9/USEFUL.txt create mode 100644 collectors/likwid/groups/sandybridge/BRANCH.txt create mode 100644 collectors/likwid/groups/sandybridge/CLOCK.txt create mode 100644 collectors/likwid/groups/sandybridge/CYCLE_ACTIVITY.txt create mode 100644 collectors/likwid/groups/sandybridge/CYCLE_STALLS.txt create mode 100644 collectors/likwid/groups/sandybridge/DATA.txt create mode 100644 collectors/likwid/groups/sandybridge/DIVIDE.txt create mode 100644 collectors/likwid/groups/sandybridge/ENERGY.txt create mode 100644 collectors/likwid/groups/sandybridge/FALSE_SHARE.txt create mode 100644 collectors/likwid/groups/sandybridge/FLOPS_AVX.txt create mode 100644 collectors/likwid/groups/sandybridge/FLOPS_DP.txt create mode 100644 collectors/likwid/groups/sandybridge/FLOPS_SP.txt create mode 100644 collectors/likwid/groups/sandybridge/ICACHE.txt create mode 100644 collectors/likwid/groups/sandybridge/L2.txt create mode 100644 collectors/likwid/groups/sandybridge/L2CACHE.txt create mode 100644 collectors/likwid/groups/sandybridge/L3.txt create mode 100644 collectors/likwid/groups/sandybridge/L3CACHE.txt create mode 100644 collectors/likwid/groups/sandybridge/PORT_USAGE.txt create mode 100644 collectors/likwid/groups/sandybridge/RECOVERY.txt create mode 100644 collectors/likwid/groups/sandybridge/TLB_DATA.txt create mode 100644 collectors/likwid/groups/sandybridge/TLB_INSTR.txt create mode 100644 collectors/likwid/groups/sandybridge/TMA.txt create mode 100644 collectors/likwid/groups/sandybridge/UOPS.txt create mode 100644 collectors/likwid/groups/sandybridge/UOPS_EXEC.txt create mode 100644 collectors/likwid/groups/sandybridge/UOPS_ISSUE.txt create mode 100644 collectors/likwid/groups/sandybridge/UOPS_RETIRE.txt create mode 100644 collectors/likwid/groups/sandybridgeEP/BRANCH.txt create mode 100644 collectors/likwid/groups/sandybridgeEP/CACHES.txt create mode 100644 collectors/likwid/groups/sandybridgeEP/CLOCK.txt create mode 100644 collectors/likwid/groups/sandybridgeEP/CYCLE_ACTIVITY.txt create mode 100644 collectors/likwid/groups/sandybridgeEP/CYCLE_STALLS.txt create mode 100644 collectors/likwid/groups/sandybridgeEP/DATA.txt create mode 100644 collectors/likwid/groups/sandybridgeEP/DIVIDE.txt create mode 100644 collectors/likwid/groups/sandybridgeEP/ENERGY.txt create mode 100644 collectors/likwid/groups/sandybridgeEP/FALSE_SHARE.txt create mode 100644 collectors/likwid/groups/sandybridgeEP/FLOPS_AVX.txt create mode 100644 collectors/likwid/groups/sandybridgeEP/FLOPS_DP.txt create mode 100644 collectors/likwid/groups/sandybridgeEP/FLOPS_SP.txt create mode 100644 collectors/likwid/groups/sandybridgeEP/ICACHE.txt create mode 100644 collectors/likwid/groups/sandybridgeEP/L2.txt create mode 100644 collectors/likwid/groups/sandybridgeEP/L2CACHE.txt create mode 100644 collectors/likwid/groups/sandybridgeEP/L3.txt create mode 100644 collectors/likwid/groups/sandybridgeEP/L3CACHE.txt create mode 100644 collectors/likwid/groups/sandybridgeEP/MEM.txt create mode 100644 collectors/likwid/groups/sandybridgeEP/MEM_DP.txt create mode 100644 collectors/likwid/groups/sandybridgeEP/MEM_SP.txt create mode 100644 collectors/likwid/groups/sandybridgeEP/NUMA.txt create mode 100644 collectors/likwid/groups/sandybridgeEP/PORT_USAGE.txt create mode 100644 collectors/likwid/groups/sandybridgeEP/QPI.txt create mode 100644 collectors/likwid/groups/sandybridgeEP/RECOVERY.txt create mode 100644 collectors/likwid/groups/sandybridgeEP/TLB_DATA.txt create mode 100644 collectors/likwid/groups/sandybridgeEP/TLB_INSTR.txt create mode 100644 collectors/likwid/groups/sandybridgeEP/TMA.txt create mode 100644 collectors/likwid/groups/sandybridgeEP/UOPS.txt create mode 100644 collectors/likwid/groups/sandybridgeEP/UOPS_EXEC.txt create mode 100644 collectors/likwid/groups/sandybridgeEP/UOPS_ISSUE.txt create mode 100644 collectors/likwid/groups/sandybridgeEP/UOPS_RETIRE.txt create mode 100644 collectors/likwid/groups/silvermont/BRANCH.txt create mode 100644 collectors/likwid/groups/silvermont/CLOCK.txt create mode 100644 collectors/likwid/groups/silvermont/DATA.txt create mode 100644 collectors/likwid/groups/silvermont/DIVIDE.txt create mode 100644 collectors/likwid/groups/silvermont/ENERGY.txt create mode 100644 collectors/likwid/groups/silvermont/ICACHE.txt create mode 100644 collectors/likwid/groups/silvermont/L2CACHE.txt create mode 100644 collectors/likwid/groups/silvermont/MEM.txt create mode 100644 collectors/likwid/groups/silvermont/TLB_DATA.txt create mode 100644 collectors/likwid/groups/silvermont/TLB_INSTR.txt create mode 100644 collectors/likwid/groups/skylake/BRANCH.txt create mode 100644 collectors/likwid/groups/skylake/CLOCK.txt create mode 100644 collectors/likwid/groups/skylake/CYCLE_ACTIVITY.txt create mode 100644 collectors/likwid/groups/skylake/CYCLE_STALLS.txt create mode 100644 collectors/likwid/groups/skylake/DATA.txt create mode 100644 collectors/likwid/groups/skylake/DIVIDE.txt create mode 100644 collectors/likwid/groups/skylake/ENERGY.txt create mode 100644 collectors/likwid/groups/skylake/FALSE_SHARE.txt create mode 100644 collectors/likwid/groups/skylake/FLOPS_AVX.txt create mode 100644 collectors/likwid/groups/skylake/FLOPS_DP.txt create mode 100644 collectors/likwid/groups/skylake/FLOPS_SP.txt create mode 100644 collectors/likwid/groups/skylake/ICACHE.txt create mode 100644 collectors/likwid/groups/skylake/L2.txt create mode 100644 collectors/likwid/groups/skylake/L2CACHE.txt create mode 100644 collectors/likwid/groups/skylake/L3.txt create mode 100644 collectors/likwid/groups/skylake/L3CACHE.txt create mode 100644 collectors/likwid/groups/skylake/MEM.txt create mode 100644 collectors/likwid/groups/skylake/MEM_DP.txt create mode 100644 collectors/likwid/groups/skylake/MEM_SP.txt create mode 100644 collectors/likwid/groups/skylake/PORT_USAGE.txt create mode 100644 collectors/likwid/groups/skylake/RECOVERY.txt create mode 100644 collectors/likwid/groups/skylake/TLB_DATA.txt create mode 100644 collectors/likwid/groups/skylake/TLB_INSTR.txt create mode 100644 collectors/likwid/groups/skylake/TMA.txt create mode 100644 collectors/likwid/groups/skylake/UOPS.txt create mode 100644 collectors/likwid/groups/skylake/UOPS_EXEC.txt create mode 100644 collectors/likwid/groups/skylake/UOPS_ISSUE.txt create mode 100644 collectors/likwid/groups/skylake/UOPS_RETIRE.txt create mode 100644 collectors/likwid/groups/skylakeX/BRANCH.txt create mode 100644 collectors/likwid/groups/skylakeX/CACHES.txt create mode 100644 collectors/likwid/groups/skylakeX/CLOCK.txt create mode 100644 collectors/likwid/groups/skylakeX/CYCLE_ACTIVITY.txt create mode 100644 collectors/likwid/groups/skylakeX/CYCLE_STALLS.txt create mode 100644 collectors/likwid/groups/skylakeX/DATA.txt create mode 100644 collectors/likwid/groups/skylakeX/DIVIDE.txt create mode 100644 collectors/likwid/groups/skylakeX/ENERGY.txt create mode 100644 collectors/likwid/groups/skylakeX/FLOPS_AVX.txt create mode 100644 collectors/likwid/groups/skylakeX/FLOPS_DP.txt create mode 100644 collectors/likwid/groups/skylakeX/FLOPS_SP.txt create mode 100644 collectors/likwid/groups/skylakeX/L2.txt create mode 100644 collectors/likwid/groups/skylakeX/L2CACHE.txt create mode 100644 collectors/likwid/groups/skylakeX/L3.txt create mode 100644 collectors/likwid/groups/skylakeX/L3CACHE.txt create mode 100644 collectors/likwid/groups/skylakeX/MEM.txt create mode 100644 collectors/likwid/groups/skylakeX/MEM_DP.txt create mode 100644 collectors/likwid/groups/skylakeX/MEM_SP.txt create mode 100644 collectors/likwid/groups/skylakeX/TLB_DATA.txt create mode 100644 collectors/likwid/groups/skylakeX/TLB_INSTR.txt create mode 100644 collectors/likwid/groups/skylakeX/TMA.txt create mode 100644 collectors/likwid/groups/skylakeX/UOPS_EXEC.txt create mode 100644 collectors/likwid/groups/skylakeX/UOPS_ISSUE.txt create mode 100644 collectors/likwid/groups/skylakeX/UOPS_RETIRE.txt create mode 100644 collectors/likwid/groups/skylakeX/UPI.txt create mode 100644 collectors/likwid/groups/westmere/BRANCH.txt create mode 100644 collectors/likwid/groups/westmere/CACHE.txt create mode 100644 collectors/likwid/groups/westmere/CLOCK.txt create mode 100644 collectors/likwid/groups/westmere/DATA.txt create mode 100644 collectors/likwid/groups/westmere/DIVIDE.txt create mode 100644 collectors/likwid/groups/westmere/FLOPS_DP.txt create mode 100644 collectors/likwid/groups/westmere/FLOPS_SP.txt create mode 100644 collectors/likwid/groups/westmere/FLOPS_X87.txt create mode 100644 collectors/likwid/groups/westmere/ICACHE.txt create mode 100644 collectors/likwid/groups/westmere/L2.txt create mode 100644 collectors/likwid/groups/westmere/L2CACHE.txt create mode 100644 collectors/likwid/groups/westmere/L3.txt create mode 100644 collectors/likwid/groups/westmere/L3CACHE.txt create mode 100644 collectors/likwid/groups/westmere/MEM.txt create mode 100644 collectors/likwid/groups/westmere/MEM_DP.txt create mode 100644 collectors/likwid/groups/westmere/MEM_SP.txt create mode 100644 collectors/likwid/groups/westmere/TLB_DATA.txt create mode 100644 collectors/likwid/groups/westmere/TLB_INSTR.txt create mode 100644 collectors/likwid/groups/westmere/UOPS.txt create mode 100644 collectors/likwid/groups/westmere/VIEW.txt create mode 100644 collectors/likwid/groups/westmereEX/BRANCH.txt create mode 100644 collectors/likwid/groups/westmereEX/CACHE.txt create mode 100644 collectors/likwid/groups/westmereEX/DATA.txt create mode 100644 collectors/likwid/groups/westmereEX/DIVIDE.txt create mode 100644 collectors/likwid/groups/westmereEX/FLOPS_DP.txt create mode 100644 collectors/likwid/groups/westmereEX/FLOPS_SP.txt create mode 100644 collectors/likwid/groups/westmereEX/FLOPS_X87.txt create mode 100644 collectors/likwid/groups/westmereEX/ICACHE.txt create mode 100644 collectors/likwid/groups/westmereEX/L2.txt create mode 100644 collectors/likwid/groups/westmereEX/L2CACHE.txt create mode 100644 collectors/likwid/groups/westmereEX/L3.txt create mode 100644 collectors/likwid/groups/westmereEX/L3CACHE.txt create mode 100644 collectors/likwid/groups/westmereEX/MEM.txt create mode 100644 collectors/likwid/groups/westmereEX/NUMA.txt create mode 100644 collectors/likwid/groups/westmereEX/TLB_DATA.txt create mode 100644 collectors/likwid/groups/westmereEX/TLB_INSTR.txt create mode 100644 collectors/likwid/groups/westmereEX/UOPS.txt create mode 100644 collectors/likwid/groups/zen/BRANCH.txt create mode 100644 collectors/likwid/groups/zen/CACHE.txt create mode 100644 collectors/likwid/groups/zen/CPI.txt create mode 100644 collectors/likwid/groups/zen/DATA.txt create mode 100644 collectors/likwid/groups/zen/DIVIDE.txt create mode 100644 collectors/likwid/groups/zen/ENERGY.txt create mode 100644 collectors/likwid/groups/zen/FLOPS_DP.txt create mode 100644 collectors/likwid/groups/zen/FLOPS_SP.txt create mode 100644 collectors/likwid/groups/zen/ICACHE.txt create mode 100644 collectors/likwid/groups/zen/L2.txt create mode 100644 collectors/likwid/groups/zen/L3.txt create mode 100644 collectors/likwid/groups/zen/MEM.txt create mode 100644 collectors/likwid/groups/zen/MEM_DP.txt create mode 100644 collectors/likwid/groups/zen/MEM_SP.txt create mode 100644 collectors/likwid/groups/zen/NUMA.txt create mode 100644 collectors/likwid/groups/zen/TLB.txt create mode 100644 collectors/likwid/groups/zen2/BRANCH.txt create mode 100644 collectors/likwid/groups/zen2/CACHE.txt create mode 100644 collectors/likwid/groups/zen2/CPI.txt create mode 100644 collectors/likwid/groups/zen2/DATA.txt create mode 100644 collectors/likwid/groups/zen2/DIVIDE.txt create mode 100644 collectors/likwid/groups/zen2/ENERGY.txt create mode 100644 collectors/likwid/groups/zen2/FLOPS_DP.txt create mode 100644 collectors/likwid/groups/zen2/FLOPS_SP.txt create mode 100644 collectors/likwid/groups/zen2/ICACHE.txt create mode 100644 collectors/likwid/groups/zen2/L2.txt create mode 100644 collectors/likwid/groups/zen2/L3.txt create mode 100644 collectors/likwid/groups/zen2/MEM.txt create mode 100644 collectors/likwid/groups/zen2/NUMA.txt create mode 100644 collectors/likwid/groups/zen2/TLB.txt create mode 100644 collectors/likwid/groups/zen3/.empty create mode 100644 collectors/likwid/liblikwid-hwloc.a create mode 100644 collectors/likwid/liblikwid.a create mode 100644 collectors/likwid/likwid-marker.h create mode 100644 collectors/likwid/likwid.h create mode 100644 collectors/likwidMetric.go diff --git a/collectors/likwid/bstrlib.h b/collectors/likwid/bstrlib.h new file mode 100644 index 0000000..02a836e --- /dev/null +++ b/collectors/likwid/bstrlib.h @@ -0,0 +1,301 @@ +/* + * ======================================================================================= + * This source file is part of the bstring string library. This code was + * written by Paul Hsieh in 2002-2008, and is covered by the BSD open source + * license and the GPL. Refer to the accompanying documentation for details + * on usage and license. + */ +/* + * bstrlib.c + * + * This file is the core module for implementing the bstring functions. + */ + +#ifndef BSTRLIB_INCLUDE +#define BSTRLIB_INCLUDE + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include + +#if !defined (BSTRLIB_VSNP_OK) && !defined (BSTRLIB_NOVSNP) +# if defined (__TURBOC__) && !defined (__BORLANDC__) +# define BSTRLIB_NOVSNP +# endif +#endif + +#define BSTR_ERR (-1) +#define BSTR_OK (0) +#define BSTR_BS_BUFF_LENGTH_GET (0) + +typedef struct tagbstring * bstring; +typedef const struct tagbstring * const_bstring; + +/* Copy functions */ +#define cstr2bstr bfromcstr +extern bstring bfromcstr (const char * str); +extern bstring bfromcstralloc (int mlen, const char * str); +extern bstring blk2bstr (const void * blk, int len); +extern char * bstr2cstr (const_bstring s, char z); +extern int bcstrfree (char * s); +extern bstring bstrcpy (const_bstring b1); +extern int bassign (bstring a, const_bstring b); +extern int bassignmidstr (bstring a, const_bstring b, int left, int len); +extern int bassigncstr (bstring a, const char * str); +extern int bassignblk (bstring a, const void * s, int len); + +/* Destroy function */ +extern int bdestroy (bstring b); + +/* Space allocation hinting functions */ +extern int balloc (bstring s, int len); +extern int ballocmin (bstring b, int len); + +/* Substring extraction */ +extern bstring bmidstr (const_bstring b, int left, int len); + +/* Various standard manipulations */ +extern int bconcat (bstring b0, const_bstring b1); +extern int bconchar (bstring b0, char c); +extern int bcatcstr (bstring b, const char * s); +extern int bcatblk (bstring b, const void * s, int len); +extern int binsert (bstring s1, int pos, const_bstring s2, unsigned char fill); +extern int binsertch (bstring s1, int pos, int len, unsigned char fill); +extern int breplace (bstring b1, int pos, int len, const_bstring b2, unsigned char fill); +extern int bdelete (bstring s1, int pos, int len); +extern int bsetstr (bstring b0, int pos, const_bstring b1, unsigned char fill); +extern int btrunc (bstring b, int n); + +/* Scan/search functions */ +extern int bstricmp (const_bstring b0, const_bstring b1); +extern int bstrnicmp (const_bstring b0, const_bstring b1, int n); +extern int biseqcaseless (const_bstring b0, const_bstring b1); +extern int bisstemeqcaselessblk (const_bstring b0, const void * blk, int len); +extern int biseq (const_bstring b0, const_bstring b1); +extern int bisstemeqblk (const_bstring b0, const void * blk, int len); +extern int biseqcstr (const_bstring b, const char * s); +extern int biseqcstrcaseless (const_bstring b, const char * s); +extern int bstrcmp (const_bstring b0, const_bstring b1); +extern int bstrncmp (const_bstring b0, const_bstring b1, int n); +extern int binstr (const_bstring s1, int pos, const_bstring s2); +extern int binstrr (const_bstring s1, int pos, const_bstring s2); +extern int binstrcaseless (const_bstring s1, int pos, const_bstring s2); +extern int binstrrcaseless (const_bstring s1, int pos, const_bstring s2); +extern int bstrchrp (const_bstring b, int c, int pos); +extern int bstrrchrp (const_bstring b, int c, int pos); +#define bstrchr(b,c) bstrchrp ((b), (c), 0) +#define bstrrchr(b,c) bstrrchrp ((b), (c), blength(b)-1) +extern int binchr (const_bstring b0, int pos, const_bstring b1); +extern int binchrr (const_bstring b0, int pos, const_bstring b1); +extern int bninchr (const_bstring b0, int pos, const_bstring b1); +extern int bninchrr (const_bstring b0, int pos, const_bstring b1); +extern int bfindreplace (bstring b, const_bstring find, const_bstring repl, int pos); +extern int bfindreplacecaseless (bstring b, const_bstring find, const_bstring repl, int pos); + +/* List of string container functions */ +struct bstrList { + int qty, mlen; + bstring * entry; +}; +extern struct bstrList * bstrListCreate (void); +extern int bstrListDestroy (struct bstrList * sl); +extern int bstrListAlloc (struct bstrList * sl, int msz); +extern int bstrListAllocMin (struct bstrList * sl, int msz); + +/* String split and join functions */ +extern struct bstrList * bsplit (const_bstring str, unsigned char splitChar); +extern struct bstrList * bsplits (const_bstring str, const_bstring splitStr); +extern struct bstrList * bsplitstr (const_bstring str, const_bstring splitStr); +extern bstring bjoin (const struct bstrList * bl, const_bstring sep); +extern int bsplitcb (const_bstring str, unsigned char splitChar, int pos, + int (* cb) (void * parm, int ofs, int len), void * parm); +extern int bsplitscb (const_bstring str, const_bstring splitStr, int pos, + int (* cb) (void * parm, int ofs, int len), void * parm); +extern int bsplitstrcb (const_bstring str, const_bstring splitStr, int pos, + int (* cb) (void * parm, int ofs, int len), void * parm); + +/* Miscellaneous functions */ +extern int bpattern (bstring b, int len); +extern int btoupper (bstring b); +extern int btolower (bstring b); +extern int bltrimws (bstring b); +extern int brtrimws (bstring b); +extern int btrimws (bstring b); + +#if !defined (BSTRLIB_NOVSNP) +extern bstring bformat (const char * fmt, ...); +extern int bformata (bstring b, const char * fmt, ...); +extern int bassignformat (bstring b, const char * fmt, ...); +extern int bvcformata (bstring b, int count, const char * fmt, va_list arglist); + +#define bvformata(ret, b, fmt, lastarg) { \ +bstring bstrtmp_b = (b); \ +const char * bstrtmp_fmt = (fmt); \ +int bstrtmp_r = BSTR_ERR, bstrtmp_sz = 16; \ + for (;;) { \ + va_list bstrtmp_arglist; \ + va_start (bstrtmp_arglist, lastarg); \ + bstrtmp_r = bvcformata (bstrtmp_b, bstrtmp_sz, bstrtmp_fmt, bstrtmp_arglist); \ + va_end (bstrtmp_arglist); \ + if (bstrtmp_r >= 0) { /* Everything went ok */ \ + bstrtmp_r = BSTR_OK; \ + break; \ + } else if (-bstrtmp_r <= bstrtmp_sz) { /* A real error? */ \ + bstrtmp_r = BSTR_ERR; \ + break; \ + } \ + bstrtmp_sz = -bstrtmp_r; /* Doubled or target size */ \ + } \ + ret = bstrtmp_r; \ +} + +#endif + +typedef int (*bNgetc) (void *parm); +typedef size_t (* bNread) (void *buff, size_t elsize, size_t nelem, void *parm); + +/* Input functions */ +extern bstring bgets (bNgetc getcPtr, void * parm, char terminator); +extern bstring bread (bNread readPtr, void * parm); +extern int bgetsa (bstring b, bNgetc getcPtr, void * parm, char terminator); +extern int bassigngets (bstring b, bNgetc getcPtr, void * parm, char terminator); +extern int breada (bstring b, bNread readPtr, void * parm); + +/* Stream functions */ +extern struct bStream * bsopen (bNread readPtr, void * parm); +extern void * bsclose (struct bStream * s); +extern int bsbufflength (struct bStream * s, int sz); +extern int bsreadln (bstring b, struct bStream * s, char terminator); +extern int bsreadlns (bstring r, struct bStream * s, const_bstring term); +extern int bsread (bstring b, struct bStream * s, int n); +extern int bsreadlna (bstring b, struct bStream * s, char terminator); +extern int bsreadlnsa (bstring r, struct bStream * s, const_bstring term); +extern int bsreada (bstring b, struct bStream * s, int n); +extern int bsunread (struct bStream * s, const_bstring b); +extern int bspeek (bstring r, const struct bStream * s); +extern int bssplitscb (struct bStream * s, const_bstring splitStr, + int (* cb) (void * parm, int ofs, const_bstring entry), void * parm); +extern int bssplitstrcb (struct bStream * s, const_bstring splitStr, + int (* cb) (void * parm, int ofs, const_bstring entry), void * parm); +extern int bseof (const struct bStream * s); + +struct tagbstring { + int mlen; + int slen; + unsigned char * data; +}; + +/* Accessor macros */ +#define blengthe(b, e) (((b) == (void *)0 || (b)->slen < 0) ? (int)(e) : ((b)->slen)) +#define blength(b) (blengthe ((b), 0)) +#define bdataofse(b, o, e) (((b) == (void *)0 || (b)->data == (void*)0) ? (char *)(e) : ((char *)(b)->data) + (o)) +#define bdataofs(b, o) (bdataofse ((b), (o), (void *)0)) +#define bdatae(b, e) (bdataofse (b, 0, e)) +#define bdata(b) (bdataofs (b, 0)) +#define bchare(b, p, e) ((((unsigned)(p)) < (unsigned)blength(b)) ? ((b)->data[(p)]) : (e)) +#define bchar(b, p) bchare ((b), (p), '\0') + +/* Static constant string initialization macro */ +#define bsStaticMlen(q,m) {(m), (int) sizeof(q)-1, (unsigned char *) ("" q "")} +#if defined(_MSC_VER) +# define bsStatic(q) bsStaticMlen(q,-32) +#endif +#ifndef bsStatic +# define bsStatic(q) bsStaticMlen(q,-__LINE__) +#endif + +/* Static constant block parameter pair */ +#define bsStaticBlkParms(q) ((void *)("" q "")), ((int) sizeof(q)-1) + +/* Reference building macros */ +#define cstr2tbstr btfromcstr +#define btfromcstr(t,s) { \ + (t).data = (unsigned char *) (s); \ + (t).slen = ((t).data) ? ((int) (strlen) ((char *)(t).data)) : 0; \ + (t).mlen = -1; \ +} +#define blk2tbstr(t,s,l) { \ + (t).data = (unsigned char *) (s); \ + (t).slen = l; \ + (t).mlen = -1; \ +} +#define btfromblk(t,s,l) blk2tbstr(t,s,l) +#define bmid2tbstr(t,b,p,l) { \ + const_bstring bstrtmp_s = (b); \ + if (bstrtmp_s && bstrtmp_s->data && bstrtmp_s->slen >= 0) { \ + int bstrtmp_left = (p); \ + int bstrtmp_len = (l); \ + if (bstrtmp_left < 0) { \ + bstrtmp_len += bstrtmp_left; \ + bstrtmp_left = 0; \ + } \ + if (bstrtmp_len > bstrtmp_s->slen - bstrtmp_left) \ + bstrtmp_len = bstrtmp_s->slen - bstrtmp_left; \ + if (bstrtmp_len <= 0) { \ + (t).data = (unsigned char *)""; \ + (t).slen = 0; \ + } else { \ + (t).data = bstrtmp_s->data + bstrtmp_left; \ + (t).slen = bstrtmp_len; \ + } \ + } else { \ + (t).data = (unsigned char *)""; \ + (t).slen = 0; \ + } \ + (t).mlen = -__LINE__; \ +} +#define btfromblkltrimws(t,s,l) { \ + int bstrtmp_idx = 0, bstrtmp_len = (l); \ + unsigned char * bstrtmp_s = (s); \ + if (bstrtmp_s && bstrtmp_len >= 0) { \ + for (; bstrtmp_idx < bstrtmp_len; bstrtmp_idx++) { \ + if (!isspace (bstrtmp_s[bstrtmp_idx])) break; \ + } \ + } \ + (t).data = bstrtmp_s + bstrtmp_idx; \ + (t).slen = bstrtmp_len - bstrtmp_idx; \ + (t).mlen = -__LINE__; \ +} +#define btfromblkrtrimws(t,s,l) { \ + int bstrtmp_len = (l) - 1; \ + unsigned char * bstrtmp_s = (s); \ + if (bstrtmp_s && bstrtmp_len >= 0) { \ + for (; bstrtmp_len >= 0; bstrtmp_len--) { \ + if (!isspace (bstrtmp_s[bstrtmp_len])) break; \ + } \ + } \ + (t).data = bstrtmp_s; \ + (t).slen = bstrtmp_len + 1; \ + (t).mlen = -__LINE__; \ +} +#define btfromblktrimws(t,s,l) { \ + int bstrtmp_idx = 0, bstrtmp_len = (l) - 1; \ + unsigned char * bstrtmp_s = (s); \ + if (bstrtmp_s && bstrtmp_len >= 0) { \ + for (; bstrtmp_idx <= bstrtmp_len; bstrtmp_idx++) { \ + if (!isspace (bstrtmp_s[bstrtmp_idx])) break; \ + } \ + for (; bstrtmp_len >= bstrtmp_idx; bstrtmp_len--) { \ + if (!isspace (bstrtmp_s[bstrtmp_len])) break; \ + } \ + } \ + (t).data = bstrtmp_s + bstrtmp_idx; \ + (t).slen = bstrtmp_len + 1 - bstrtmp_idx; \ + (t).mlen = -__LINE__; \ +} + +/* Write protection macros */ +#define bwriteprotect(t) { if ((t).mlen >= 0) (t).mlen = -1; } +#define bwriteallow(t) { if ((t).mlen == -1) (t).mlen = (t).slen + ((t).slen == 0); } +#define biswriteprotected(t) ((t).mlen <= 0) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/collectors/likwid/groups/CLX/BRANCH.txt b/collectors/likwid/groups/CLX/BRANCH.txt new file mode 100644 index 0000000..b8d41b2 --- /dev/null +++ b/collectors/likwid/groups/CLX/BRANCH.txt @@ -0,0 +1,31 @@ +SHORT Branch prediction miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 BR_INST_RETIRED_ALL_BRANCHES +PMC1 BR_MISP_RETIRED_ALL_BRANCHES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Branch rate PMC0/FIXC0 +Branch misprediction rate PMC1/FIXC0 +Branch misprediction ratio PMC1/PMC0 +Instructions per branch FIXC0/PMC0 + +LONG +Formulas: +Branch rate = BR_INST_RETIRED_ALL_BRANCHES/INSTR_RETIRED_ANY +Branch misprediction rate = BR_MISP_RETIRED_ALL_BRANCHES/INSTR_RETIRED_ANY +Branch misprediction ratio = BR_MISP_RETIRED_ALL_BRANCHES/BR_INST_RETIRED_ALL_BRANCHES +Instructions per branch = INSTR_RETIRED_ANY/BR_INST_RETIRED_ALL_BRANCHES +- +The rates state how often on average a branch or a mispredicted branch occurred +per instruction retired in total. The branch misprediction ratio sets directly +into relation what ratio of all branch instruction where mispredicted. +Instructions per branch is 1/branch rate. + diff --git a/collectors/likwid/groups/CLX/CACHES.txt b/collectors/likwid/groups/CLX/CACHES.txt new file mode 100644 index 0000000..c700dd4 --- /dev/null +++ b/collectors/likwid/groups/CLX/CACHES.txt @@ -0,0 +1,143 @@ +SHORT Cache bandwidth in MBytes/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 L1D_REPLACEMENT +PMC1 L1D_M_EVICT +PMC2 L2_LINES_IN_ALL +PMC3 L2_TRANS_L2_WB +CBOX0C1 LLC_VICTIMS_M_STATE +CBOX1C1 LLC_VICTIMS_M_STATE +CBOX2C1 LLC_VICTIMS_M_STATE +CBOX3C1 LLC_VICTIMS_M_STATE +CBOX4C1 LLC_VICTIMS_M_STATE +CBOX5C1 LLC_VICTIMS_M_STATE +CBOX6C1 LLC_VICTIMS_M_STATE +CBOX7C1 LLC_VICTIMS_M_STATE +CBOX8C1 LLC_VICTIMS_M_STATE +CBOX9C1 LLC_VICTIMS_M_STATE +CBOX10C1 LLC_VICTIMS_M_STATE +CBOX11C1 LLC_VICTIMS_M_STATE +CBOX12C1 LLC_VICTIMS_M_STATE +CBOX13C1 LLC_VICTIMS_M_STATE +CBOX14C1 LLC_VICTIMS_M_STATE +CBOX15C1 LLC_VICTIMS_M_STATE +CBOX16C1 LLC_VICTIMS_M_STATE +CBOX17C1 LLC_VICTIMS_M_STATE +CBOX18C1 LLC_VICTIMS_M_STATE +CBOX19C1 LLC_VICTIMS_M_STATE +CBOX20C1 LLC_VICTIMS_M_STATE +CBOX21C1 LLC_VICTIMS_M_STATE +CBOX22C1 LLC_VICTIMS_M_STATE +CBOX23C1 LLC_VICTIMS_M_STATE +CBOX24C1 LLC_VICTIMS_M_STATE +CBOX25C1 LLC_VICTIMS_M_STATE +CBOX26C1 LLC_VICTIMS_M_STATE +CBOX27C1 LLC_VICTIMS_M_STATE +CBOX0C0 LLC_LOOKUP_DATA_READ +CBOX1C0 LLC_LOOKUP_DATA_READ +CBOX2C0 LLC_LOOKUP_DATA_READ +CBOX3C0 LLC_LOOKUP_DATA_READ +CBOX4C0 LLC_LOOKUP_DATA_READ +CBOX5C0 LLC_LOOKUP_DATA_READ +CBOX6C0 LLC_LOOKUP_DATA_READ +CBOX7C0 LLC_LOOKUP_DATA_READ +CBOX8C0 LLC_LOOKUP_DATA_READ +CBOX9C0 LLC_LOOKUP_DATA_READ +CBOX10C0 LLC_LOOKUP_DATA_READ +CBOX11C0 LLC_LOOKUP_DATA_READ +CBOX12C0 LLC_LOOKUP_DATA_READ +CBOX13C0 LLC_LOOKUP_DATA_READ +CBOX14C0 LLC_LOOKUP_DATA_READ +CBOX15C0 LLC_LOOKUP_DATA_READ +CBOX16C0 LLC_LOOKUP_DATA_READ +CBOX17C0 LLC_LOOKUP_DATA_READ +CBOX18C0 LLC_LOOKUP_DATA_READ +CBOX19C0 LLC_LOOKUP_DATA_READ +CBOX20C0 LLC_LOOKUP_DATA_READ +CBOX21C0 LLC_LOOKUP_DATA_READ +CBOX22C0 LLC_LOOKUP_DATA_READ +CBOX23C0 LLC_LOOKUP_DATA_READ +CBOX24C0 LLC_LOOKUP_DATA_READ +CBOX25C0 LLC_LOOKUP_DATA_READ +CBOX26C0 LLC_LOOKUP_DATA_READ +CBOX27C0 LLC_LOOKUP_DATA_READ +MBOX0C0 CAS_COUNT_RD +MBOX0C1 CAS_COUNT_WR +MBOX1C0 CAS_COUNT_RD +MBOX1C1 CAS_COUNT_WR +MBOX2C0 CAS_COUNT_RD +MBOX2C1 CAS_COUNT_WR +MBOX3C0 CAS_COUNT_RD +MBOX3C1 CAS_COUNT_WR +MBOX4C0 CAS_COUNT_RD +MBOX4C1 CAS_COUNT_WR +MBOX5C0 CAS_COUNT_RD +MBOX5C1 CAS_COUNT_WR + + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L2 to L1 load bandwidth [MBytes/s] 1.0E-06*PMC0*64.0/time +L2 to L1 load data volume [GBytes] 1.0E-09*PMC0*64.0 +L1 to L2 evict bandwidth [MBytes/s] 1.0E-06*PMC1*64.0/time +L1 to L2 evict data volume [GBytes] 1.0E-09*PMC1*64.0 +L1 to/from L2 bandwidth [MBytes/s] 1.0E-06*(PMC0+PMC1)*64.0/time +L1 to/from L2 data volume [GBytes] 1.0E-09*(PMC0+PMC1)*64.0 +L3 to L2 load bandwidth [MBytes/s] 1.0E-06*PMC2*64.0/time +L3 to L2 load data volume [GBytes] 1.0E-09*PMC2*64.0 +L2 to L3 evict bandwidth [MBytes/s] 1.0E-06*PMC3*64.0/time +L2 to L3 evict data volume [GBytes] 1.0E-09*PMC3*64.0 +L2 to/from L3 bandwidth [MBytes/s] 1.0E-06*(PMC2+PMC3)*64.0/time +L2 to/from L3 data volume [GBytes] 1.0E-09*(PMC2+PMC3)*64.0 +System to L3 bandwidth [MBytes/s] 1.0E-06*(CBOX0C0+CBOX1C0+CBOX2C0+CBOX3C0+CBOX4C0+CBOX5C0+CBOX6C0+CBOX7C0+CBOX8C0+CBOX9C0+CBOX10C0+CBOX11C0+CBOX12C0+CBOX13C0+CBOX14C0+CBOX15C0+CBOX16C0+CBOX17C0+CBOX18C0+CBOX19C0+CBOX20C0+CBOX21C0+CBOX22C0+CBOX23C0+CBOX24C0+CBOX25C0+CBOX26C0+CBOX27C0)*64.0/time +System to L3 data volume [GBytes] 1.0E-09*(CBOX0C0+CBOX1C0+CBOX2C0+CBOX3C0+CBOX4C0+CBOX5C0+CBOX6C0+CBOX7C0+CBOX8C0+CBOX9C0+CBOX10C0+CBOX11C0+CBOX12C0+CBOX13C0+CBOX14C0+CBOX15C0+CBOX16C0+CBOX17C0+CBOX18C0+CBOX19C0+CBOX20C0+CBOX21C0+CBOX22C0+CBOX23C0+CBOX24C0+CBOX25C0+CBOX26C0+CBOX27C0)*64.0 +L3 to system bandwidth [MBytes/s] 1.0E-06*(CBOX0C1+CBOX1C1+CBOX2C1+CBOX3C1+CBOX4C1+CBOX5C1+CBOX6C1+CBOX7C1+CBOX8C1+CBOX9C1+CBOX10C1+CBOX11C1+CBOX12C1+CBOX13C1+CBOX14C1+CBOX15C1+CBOX16C1+CBOX17C1+CBOX18C1+CBOX19C1+CBOX20C1+CBOX21C1+CBOX22C1+CBOX23C1+CBOX24C1+CBOX25C1+CBOX26C1+CBOX27C1)*64/time +L3 to system data volume [GBytes] 1.0E-09*(CBOX0C1+CBOX1C1+CBOX2C1+CBOX3C1+CBOX4C1+CBOX5C1+CBOX6C1+CBOX7C1+CBOX8C1+CBOX9C1+CBOX10C1+CBOX11C1+CBOX12C1+CBOX13C1+CBOX14C1+CBOX15C1+CBOX16C1+CBOX17C1+CBOX18C1+CBOX19C1+CBOX20C1+CBOX21C1+CBOX22C1+CBOX23C1+CBOX24C1+CBOX25C1+CBOX26C1+CBOX27C1)*64 +L3 to/from system bandwidth [MBytes/s] 1.0E-06*(CBOX0C0+CBOX1C0+CBOX2C0+CBOX3C0+CBOX4C0+CBOX5C0+CBOX6C0+CBOX7C0+CBOX8C0+CBOX9C0+CBOX10C0+CBOX11C0+CBOX12C0+CBOX13C0+CBOX14C0+CBOX15C0+CBOX16C0+CBOX17C0+CBOX18C0+CBOX19C0+CBOX20C0+CBOX21C0+CBOX22C0+CBOX23C0+CBOX24C0+CBOX25C0+CBOX26C0+CBOX27C0+CBOX0C1+CBOX1C1+CBOX2C1+CBOX3C1+CBOX4C1+CBOX5C1+CBOX6C1+CBOX7C1+CBOX8C1+CBOX9C1+CBOX10C1+CBOX11C1+CBOX12C1+CBOX13C1+CBOX14C1+CBOX15C1+CBOX16C1+CBOX17C1+CBOX18C1+CBOX19C1+CBOX20C1+CBOX21C1+CBOX22C1+CBOX23C1+CBOX24C1+CBOX25C1+CBOX26C1+CBOX27C1)*64.0/time +L3 to/from system data volume [GBytes] 1.0E-09*(CBOX0C0+CBOX1C0+CBOX2C0+CBOX3C0+CBOX4C0+CBOX5C0+CBOX6C0+CBOX7C0+CBOX8C0+CBOX9C0+CBOX10C0+CBOX11C0+CBOX12C0+CBOX13C0+CBOX14C0+CBOX15C0+CBOX16C0+CBOX17C0+CBOX18C0+CBOX19C0+CBOX20C0+CBOX21C0+CBOX22C0+CBOX23C0+CBOX24C0+CBOX25C0+CBOX26C0+CBOX27C0+CBOX0C1+CBOX1C1+CBOX2C1+CBOX3C1+CBOX4C1+CBOX5C1+CBOX6C1+CBOX7C1+CBOX8C1+CBOX9C1+CBOX10C1+CBOX11C1+CBOX12C1+CBOX13C1+CBOX14C1+CBOX15C1+CBOX16C1+CBOX17C1+CBOX18C1+CBOX19C1+CBOX20C1+CBOX21C1+CBOX22C1+CBOX23C1+CBOX24C1+CBOX25C1+CBOX26C1+CBOX27C1)*64.0 +Memory read bandwidth [MBytes/s] 1.0E-06*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0)*64.0/time +Memory read data volume [GBytes] 1.0E-09*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0)*64.0 +Memory write bandwidth [MBytes/s] 1.0E-06*(MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1)*64.0/time +Memory write data volume [GBytes] 1.0E-09*(MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1)*64.0 +Memory bandwidth [MBytes/s] 1.0E-06*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1)*64.0/time +Memory data volume [GBytes] 1.0E-09*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1)*64.0 + +LONG +Formulas: +L2 to L1 load bandwidth [MBytes/s] = 1.0E-06*L1D_REPLACEMENT*64/time +L2 to L1 load data volume [GBytes] = 1.0E-09*L1D_REPLACEMENT*64 +L1 to L2 evict bandwidth [MBytes/s] = 1.0E-06*L1D_M_EVICT*64/time +L1 to L2 evict data volume [GBytes] = 1.0E-09*L1D_M_EVICT*64 +L1 to/from L2 bandwidth [MBytes/s] = 1.0E-06*(L1D_REPLACEMENT+L1D_M_EVICT)*64/time +L1 to/from L2 data volume [GBytes] = 1.0E-09*(L1D_REPLACEMENT+L1D_M_EVICT)*64 +L3 to L2 load bandwidth [MBytes/s] = 1.0E-06*L2_LINES_IN_ALL*64/time +L3 to L2 load data volume [GBytes] = 1.0E-09*L2_LINES_IN_ALL*64 +L2 to L3 evict bandwidth [MBytes/s] = 1.0E-06*L2_TRANS_L2_WB*64/time +L2 to L3 evict data volume [GBytes] = 1.0E-09*L2_TRANS_L2_WB*64 +L2 to/from L3 bandwidth [MBytes/s] = 1.0E-06*(L2_LINES_IN_ALL+L2_TRANS_L2_WB)*64/time +L2 to/from L3 data volume [GBytes] = 1.0E-09*(L2_LINES_IN_ALL+L2_TRANS_L2_WB)*64 +System to L3 bandwidth [MBytes/s] = 1.0E-06*(SUM(LLC_LOOKUP_DATA_READ))*64/time +System to L3 data volume [GBytes] = 1.0E-09*(SUM(LLC_LOOKUP_DATA_READ))*64 +L3 to system bandwidth [MBytes/s] = 1.0E-06*(SUM(LLC_VICTIMS_M_STATE))*64/time +L3 to system data volume [GBytes] = 1.0E-09*(SUM(LLC_VICTIMS_M_STATE))*64 +L3 to/from system bandwidth [MBytes/s] = 1.0E-06*(SUM(LLC_LOOKUP_DATA_READ)+SUM(LLC_VICTIMS_M_STATE))*64/time +L3 to/from system data volume [GBytes] = 1.0E-09*(SUM(LLC_LOOKUP_DATA_READ)+SUM(LLC_VICTIMS_M_STATE))*64 +Memory read bandwidth [MBytes/s] = 1.0E-06*(SUM(CAS_COUNT_RD))*64.0/time +Memory read data volume [GBytes] = 1.0E-09*(SUM(CAS_COUNT_RD))*64.0 +Memory write bandwidth [MBytes/s] = 1.0E-06*(SUM(CAS_COUNT_WR))*64.0/time +Memory write data volume [GBytes] = 1.0E-09*(SUM(CAS_COUNT_WR))*64.0 +Memory bandwidth [MBytes/s] = 1.0E-06*(SUM(CAS_COUNT_RD)+SUM(CAS_COUNT_WR))*64.0/time +Memory data volume [GBytes] = 1.0E-09*(SUM(CAS_COUNT_RD)+SUM(CAS_COUNT_WR))*64.0 +- +Group to measure cache transfers between L1 and Memory. Please notice that the +L3 to/from system metrics contain any traffic to the system (memory, +Intel QPI, etc.) but don't seem to handle anything because commonly memory read +bandwidth and L3 to L2 bandwidth is higher as the memory to L3 bandwidth. + diff --git a/collectors/likwid/groups/CLX/CLOCK.txt b/collectors/likwid/groups/CLX/CLOCK.txt new file mode 100644 index 0000000..b81bee6 --- /dev/null +++ b/collectors/likwid/groups/CLX/CLOCK.txt @@ -0,0 +1,26 @@ +SHORT Power and Energy consumption + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PWR0 PWR_PKG_ENERGY +UBOXFIX UNCORE_CLOCK + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +Uncore Clock [MHz] 1.E-06*UBOXFIX/time +CPI FIXC1/FIXC0 +Energy [J] PWR0 +Power [W] PWR0/time + +LONG +Formulas: +Power = PWR_PKG_ENERGY / time +Uncore Clock [MHz] = 1.E-06 * UNCORE_CLOCK / time +- +Broadwell implements the new RAPL interface. This interface enables to +monitor the consumed energy on the package (socket) level. + diff --git a/collectors/likwid/groups/CLX/CYCLE_ACTIVITY.txt b/collectors/likwid/groups/CLX/CYCLE_ACTIVITY.txt new file mode 100644 index 0000000..c432a44 --- /dev/null +++ b/collectors/likwid/groups/CLX/CYCLE_ACTIVITY.txt @@ -0,0 +1,38 @@ +SHORT Cycle Activities + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 CYCLE_ACTIVITY_CYCLES_L2_PENDING +PMC1 CYCLE_ACTIVITY_CYCLES_LDM_PENDING +PMC2 CYCLE_ACTIVITY_CYCLES_L1D_PENDING +PMC3 CYCLE_ACTIVITY_CYCLES_NO_EXECUTE + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Cycles without execution [%] (PMC3/FIXC1)*100 +Cycles without execution due to L1D [%] (PMC2/FIXC1)*100 +Cycles without execution due to L2 [%] (PMC0/FIXC1)*100 +Cycles without execution due to memory loads [%] (PMC1/FIXC1)*100 + +LONG +Formulas: +Cycles without execution [%] = CYCLE_ACTIVITY_CYCLES_NO_EXECUTE/CPU_CLK_UNHALTED_CORE*100 +Cycles with stalls due to L1D [%] = CYCLE_ACTIVITY_CYCLES_L1D_PENDING/CPU_CLK_UNHALTED_CORE*100 +Cycles with stalls due to L2 [%] = CYCLE_ACTIVITY_CYCLES_L2_PENDING/CPU_CLK_UNHALTED_CORE*100 +Cycles without execution due to memory loads [%] = CYCLE_ACTIVITY_CYCLES_LDM_PENDING/CPU_CLK_UNHALTED_CORE*100 +-- +This performance group measures the cycles while waiting for data from the cache +and memory hierarchy. +CYCLE_ACTIVITY_CYCLES_NO_EXECUTE: Counts number of cycles nothing is executed on +any execution port. +CYCLE_ACTIVITY_CYCLES_L1D_PENDING: Cycles while L1 cache miss demand load is +outstanding. +CYCLE_ACTIVITY_CYCLES_L2_PENDING: Cycles while L2 cache miss demand load is +outstanding. +CYCLE_ACTIVITY_CYCLES_LDM_PENDING: Cycles while memory subsystem has an +outstanding load. diff --git a/collectors/likwid/groups/CLX/CYCLE_STALLS.txt b/collectors/likwid/groups/CLX/CYCLE_STALLS.txt new file mode 100644 index 0000000..795aeb9 --- /dev/null +++ b/collectors/likwid/groups/CLX/CYCLE_STALLS.txt @@ -0,0 +1,45 @@ +SHORT Cycle Activities (Stalls) + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 CYCLE_ACTIVITY_STALLS_L2_PENDING +PMC1 CYCLE_ACTIVITY_STALLS_LDM_PENDING +PMC2 CYCLE_ACTIVITY_STALLS_L1D_PENDING +PMC3 CYCLE_ACTIVITY_STALLS_TOTAL + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Total execution stalls PMC3 +Stalls caused by L1D misses [%] (PMC2/PMC3)*100 +Stalls caused by L2 misses [%] (PMC0/PMC3)*100 +Stalls caused by memory loads [%] (PMC1/PMC3)*100 +Execution stall rate [%] (PMC3/FIXC1)*100 +Stalls caused by L1D misses rate [%] (PMC2/FIXC1)*100 +Stalls caused by L2 misses rate [%] (PMC0/FIXC1)*100 +Stalls caused by memory loads rate [%] (PMC1/FIXC1)*100 + +LONG +Formulas: +Total execution stalls = CYCLE_ACTIVITY_STALLS_TOTAL +Stalls caused by L1D misses [%] = (CYCLE_ACTIVITY_STALLS_L1D_PENDING/CYCLE_ACTIVITY_STALLS_TOTAL)*100 +Stalls caused by L2 misses [%] = (CYCLE_ACTIVITY_STALLS_L2_PENDING/CYCLE_ACTIVITY_STALLS_TOTAL)*100 +Stalls caused by memory loads [%] = (CYCLE_ACTIVITY_STALLS_LDM_PENDING/CYCLE_ACTIVITY_STALLS_TOTAL)*100 +Execution stall rate [%] = (CYCLE_ACTIVITY_STALLS_TOTAL/CPU_CLK_UNHALTED_CORE)*100 +Stalls caused by L1D misses rate [%] = (CYCLE_ACTIVITY_STALLS_L1D_PENDING/CPU_CLK_UNHALTED_CORE)*100 +Stalls caused by L2 misses rate [%] = (CYCLE_ACTIVITY_STALLS_L2_PENDING/CPU_CLK_UNHALTED_CORE)*100 +Stalls caused by memory loads rate [%] = (CYCLE_ACTIVITY_STALLS_LDM_PENDING/CPU_CLK_UNHALTED_CORE)*100 +-- +This performance group measures the stalls caused by data traffic in the cache +hierarchy. +CYCLE_ACTIVITY_STALLS_TOTAL: Total execution stalls. +CYCLE_ACTIVITY_STALLS_L1D_PENDING: Execution stalls while L1 cache miss demand +load is outstanding. +CYCLE_ACTIVITY_STALLS_L2_PENDING: Execution stalls while L2 cache miss demand +load is outstanding. +CYCLE_ACTIVITY_STALLS_LDM_PENDING: Execution stalls while memory subsystem has +an outstanding load. diff --git a/collectors/likwid/groups/CLX/DATA.txt b/collectors/likwid/groups/CLX/DATA.txt new file mode 100644 index 0000000..4e6e938 --- /dev/null +++ b/collectors/likwid/groups/CLX/DATA.txt @@ -0,0 +1,22 @@ +SHORT Load to store ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 MEM_INST_RETIRED_ALL_LOADS +PMC1 MEM_INST_RETIRED_ALL_STORES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Load to store ratio PMC0/PMC1 + +LONG +Formulas: +Load to store ratio = MEM_INST_RETIRED_ALL_LOADS/MEM_INST_RETIRED_ALL_STORES +- +This is a metric to determine your load to store ratio. + diff --git a/collectors/likwid/groups/CLX/DIVIDE.txt b/collectors/likwid/groups/CLX/DIVIDE.txt new file mode 100644 index 0000000..2c6222d --- /dev/null +++ b/collectors/likwid/groups/CLX/DIVIDE.txt @@ -0,0 +1,24 @@ +SHORT Divide unit information + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 ARITH_DIVIDER_COUNT +PMC1 ARITH_DIVIDER_ACTIVE + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Number of divide ops PMC0 +Avg. divide unit usage duration PMC1/PMC0 + +LONG +Formulas: +Number of divide ops = ARITH_DIVIDER_COUNT +Avg. divide unit usage duration = ARITH_DIVIDER_ACTIVE/ARITH_DIVIDER_COUNT +-- +This performance group measures the average latency of divide operations diff --git a/collectors/likwid/groups/CLX/ENERGY.txt b/collectors/likwid/groups/CLX/ENERGY.txt new file mode 100644 index 0000000..fe7829f --- /dev/null +++ b/collectors/likwid/groups/CLX/ENERGY.txt @@ -0,0 +1,35 @@ +SHORT Power and Energy consumption + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +TMP0 TEMP_CORE +PWR0 PWR_PKG_ENERGY +PWR1 PWR_PP0_ENERGY +PWR3 PWR_DRAM_ENERGY + + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Temperature [C] TMP0 +Energy [J] PWR0 +Power [W] PWR0/time +Energy PP0 [J] PWR1 +Power PP0 [W] PWR1/time +Energy DRAM [J] PWR3 +Power DRAM [W] PWR3/time + +LONG +Formulas: +Power = PWR_PKG_ENERGY / time +Power PP0 = PWR_PP0_ENERGY / time +Power DRAM = PWR_DRAM_ENERGY / time +- +Broadwell implements the new RAPL interface. This interface enables to +monitor the consumed energy on the package (socket) and DRAM level. + diff --git a/collectors/likwid/groups/CLX/FLOPS_AVX.txt b/collectors/likwid/groups/CLX/FLOPS_AVX.txt new file mode 100644 index 0000000..e44a913 --- /dev/null +++ b/collectors/likwid/groups/CLX/FLOPS_AVX.txt @@ -0,0 +1,25 @@ +SHORT Packed AVX MFLOP/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE +PMC1 FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE +PMC2 FP_ARITH_INST_RETIRED_512B_PACKED_SINGLE +PMC3 FP_ARITH_INST_RETIRED_512B_PACKED_DOUBLE + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Packed SP [MFLOP/s] 1.0E-06*(PMC0*8.0+PMC2*16.0)/time +Packed DP [MFLOP/s] 1.0E-06*(PMC1*4.0+PMC3*8.0)/time + +LONG +Formulas: +Packed SP [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE*8+FP_ARITH_INST_RETIRED_512B_PACKED_SINGLE*16)/runtime +Packed DP [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE*4+FP_ARITH_INST_RETIRED_512B_PACKED_DOUBLE*8)/runtime +- +Packed 32b AVX FLOPs rates. diff --git a/collectors/likwid/groups/CLX/FLOPS_DP.txt b/collectors/likwid/groups/CLX/FLOPS_DP.txt new file mode 100644 index 0000000..7d6af79 --- /dev/null +++ b/collectors/likwid/groups/CLX/FLOPS_DP.txt @@ -0,0 +1,34 @@ +SHORT Double Precision MFLOP/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 FP_ARITH_INST_RETIRED_128B_PACKED_DOUBLE +PMC1 FP_ARITH_INST_RETIRED_SCALAR_DOUBLE +PMC2 FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE +PMC3 FP_ARITH_INST_RETIRED_512B_PACKED_DOUBLE + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +DP [MFLOP/s] 1.0E-06*(PMC0*2.0+PMC1+PMC2*4.0+PMC3*8.0)/time +AVX DP [MFLOP/s] 1.0E-06*(PMC2*4.0+PMC3*8.0)/time +AVX512 DP [MFLOP/s] 1.0E-06*(PMC3*8.0)/time +Packed [MUOPS/s] 1.0E-06*(PMC0+PMC2+PMC3)/time +Scalar [MUOPS/s] 1.0E-06*PMC1/time +Vectorization ratio 100*(PMC0+PMC2+PMC3)/(PMC0+PMC1+PMC2+PMC3) + +LONG +Formulas: +DP [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_128B_PACKED_DOUBLE*2+FP_ARITH_INST_RETIRED_SCALAR_DOUBLE+FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE*4+FP_ARITH_INST_RETIRED_512B_PACKED_DOUBLE*8)/runtime +AVX DP [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE*4+FP_ARITH_INST_RETIRED_512B_PACKED_DOUBLE*8)/runtime +AVX512 DP [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_512B_PACKED_DOUBLE*8)/runtime +Packed [MUOPS/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_128B_PACKED_DOUBLE+FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE+FP_ARITH_INST_RETIRED_512B_PACKED_DOUBLE)/runtime +Scalar [MUOPS/s] = 1.0E-06*FP_ARITH_INST_RETIRED_SCALAR_DOUBLE/runtime +Vectorization ratio = 100*(FP_ARITH_INST_RETIRED_128B_PACKED_DOUBLE+FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE+FP_ARITH_INST_RETIRED_512B_PACKED_DOUBLE)/(FP_ARITH_INST_RETIRED_SCALAR_DOUBLE+FP_ARITH_INST_RETIRED_128B_PACKED_DOUBLE+FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE+FP_ARITH_INST_RETIRED_512B_PACKED_DOUBLE) +- +SSE scalar and packed double precision FLOP rates. + diff --git a/collectors/likwid/groups/CLX/FLOPS_SP.txt b/collectors/likwid/groups/CLX/FLOPS_SP.txt new file mode 100644 index 0000000..39fb08d --- /dev/null +++ b/collectors/likwid/groups/CLX/FLOPS_SP.txt @@ -0,0 +1,34 @@ +SHORT Single Precision MFLOP/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 FP_ARITH_INST_RETIRED_128B_PACKED_SINGLE +PMC1 FP_ARITH_INST_RETIRED_SCALAR_SINGLE +PMC2 FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE +PMC3 FP_ARITH_INST_RETIRED_512B_PACKED_SINGLE + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +SP [MFLOP/s] 1.0E-06*(PMC0*4.0+PMC1+PMC2*8.0+PMC3*16.0)/time +AVX SP [MFLOP/s] 1.0E-06*(PMC2*8.0+PMC3*16.0)/time +AVX512 SP [MFLOP/s] 1.0E-06*(PMC3*16.0)/time +Packed [MUOPS/s] 1.0E-06*(PMC0+PMC2+PMC3)/time +Scalar [MUOPS/s] 1.0E-06*PMC1/time +Vectorization ratio 100*(PMC0+PMC2+PMC3)/(PMC0+PMC1+PMC2+PMC3) + +LONG +Formulas: +SP [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_128B_PACKED_SINGLE*4+FP_ARITH_INST_RETIRED_SCALAR_SINGLE+FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE*8+FP_ARITH_INST_RETIRED_512B_PACKED_SINGLE*16)/runtime +AVX SP [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE*8+FP_ARITH_INST_RETIRED_512B_PACKED_SINGLE*16)/runtime +AVX512 SP [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_512B_PACKED_SINGLE*16)/runtime +Packed [MUOPS/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_128B_PACKED_SINGLE+FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE+FP_ARITH_INST_RETIRED_512B_PACKED_SINGLE)/runtime +Scalar [MUOPS/s] = 1.0E-06*FP_ARITH_INST_RETIRED_SCALAR_SINGLE/runtime +Vectorization ratio = 100*(FP_ARITH_INST_RETIRED_128B_PACKED_SINGLE+FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE+FP_ARITH_INST_RETIRED_512B_PACKED_SINGLE)/(FP_ARITH_INST_RETIRED_SCALAR_SINGLE+FP_ARITH_INST_RETIRED_128B_PACKED_SINGLE+FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE+FP_ARITH_INST_RETIRED_512B_PACKED_SINGLE) +- +SSE scalar and packed single precision FLOP rates. + diff --git a/collectors/likwid/groups/CLX/L2.txt b/collectors/likwid/groups/CLX/L2.txt new file mode 100644 index 0000000..1a92a95 --- /dev/null +++ b/collectors/likwid/groups/CLX/L2.txt @@ -0,0 +1,38 @@ +SHORT L2 cache bandwidth in MBytes/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 L1D_REPLACEMENT +PMC1 L1D_M_EVICT +PMC2 ICACHE_64B_IFTAG_MISS + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L2D load bandwidth [MBytes/s] 1.0E-06*PMC0*64.0/time +L2D load data volume [GBytes] 1.0E-09*PMC0*64.0 +L2D evict bandwidth [MBytes/s] 1.0E-06*PMC1*64.0/time +L2D evict data volume [GBytes] 1.0E-09*PMC1*64.0 +L2 bandwidth [MBytes/s] 1.0E-06*(PMC0+PMC1+PMC2)*64.0/time +L2 data volume [GBytes] 1.0E-09*(PMC0+PMC1+PMC2)*64.0 + +LONG +Formulas: +L2D load bandwidth [MBytes/s] = 1.0E-06*L1D_REPLACEMENT*64.0/time +L2D load data volume [GBytes] = 1.0E-09*L1D_REPLACEMENT*64.0 +L2D evict bandwidth [MBytes/s] = 1.0E-06*L1D_M_EVICT*64.0/time +L2D evict data volume [GBytes] = 1.0E-09*L1D_M_EVICT*64.0 +L2 bandwidth [MBytes/s] = 1.0E-06*(L1D_REPLACEMENT+L1D_M_EVICT+ICACHE_64B_IFTAG_MISS)*64/time +L2 data volume [GBytes] = 1.0E-09*(L1D_REPLACEMENT+L1D_M_EVICT+ICACHE_64B_IFTAG_MISS)*64 +- +Profiling group to measure L2 cache bandwidth. The bandwidth is computed by the +number of cache line allocated in the L1 and the number of modified cache lines +evicted from the L1. The group also output total data volume transferred between +L2 and L1. Note that this bandwidth also includes data transfers due to a write +allocate load on a store miss in L1 and traffic caused by misses in the +L1 instruction cache. + diff --git a/collectors/likwid/groups/CLX/L2CACHE.txt b/collectors/likwid/groups/CLX/L2CACHE.txt new file mode 100644 index 0000000..9b5dd4b --- /dev/null +++ b/collectors/likwid/groups/CLX/L2CACHE.txt @@ -0,0 +1,34 @@ +SHORT L2 cache miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 L2_TRANS_ALL_REQUESTS +PMC1 L2_RQSTS_MISS + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L2 request rate PMC0/FIXC0 +L2 miss rate PMC1/FIXC0 +L2 miss ratio PMC1/PMC0 + +LONG +Formulas: +L2 request rate = L2_TRANS_ALL_REQUESTS/INSTR_RETIRED_ANY +L2 miss rate = L2_RQSTS_MISS/INSTR_RETIRED_ANY +L2 miss ratio = L2_RQSTS_MISS/L2_TRANS_ALL_REQUESTS +- +This group measures the locality of your data accesses with regard to the +L2 cache. L2 request rate tells you how data intensive your code is +or how many data accesses you have on average per instruction. +The L2 miss rate gives a measure how often it was necessary to get +cache lines from memory. And finally L2 miss ratio tells you how many of your +memory references required a cache line to be loaded from a higher level. +While the# data cache miss rate might be given by your algorithm you should +try to get data cache miss ratio as low as possible by increasing your cache reuse. + + diff --git a/collectors/likwid/groups/CLX/L3.txt b/collectors/likwid/groups/CLX/L3.txt new file mode 100644 index 0000000..98d1d9e --- /dev/null +++ b/collectors/likwid/groups/CLX/L3.txt @@ -0,0 +1,36 @@ +SHORT L3 cache bandwidth in MBytes/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 L2_LINES_IN_ALL +PMC1 L2_TRANS_L2_WB + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L3 load bandwidth [MBytes/s] 1.0E-06*PMC0*64.0/time +L3 load data volume [GBytes] 1.0E-09*PMC0*64.0 +L3 evict bandwidth [MBytes/s] 1.0E-06*PMC1*64.0/time +L3 evict data volume [GBytes] 1.0E-09*PMC1*64.0 +L3 bandwidth [MBytes/s] 1.0E-06*(PMC0+PMC1)*64.0/time +L3 data volume [GBytes] 1.0E-09*(PMC0+PMC1)*64.0 + +LONG +Formulas: +L3 load bandwidth [MBytes/s] = 1.0E-06*L2_LINES_IN_ALL*64.0/time +L3 load data volume [GBytes] = 1.0E-09*L2_LINES_IN_ALL*64.0 +L3 evict bandwidth [MBytes/s] = 1.0E-06*L2_TRANS_L2_WB*64.0/time +L3 evict data volume [GBytes] = 1.0E-09*L2_TRANS_L2_WB*64.0 +L3 bandwidth [MBytes/s] = 1.0E-06*(L2_LINES_IN_ALL+L2_TRANS_L2_WB)*64/time +L3 data volume [GBytes] = 1.0E-09*(L2_LINES_IN_ALL+L2_TRANS_L2_WB)*64 +- +Profiling group to measure L3 cache bandwidth. The bandwidth is computed by the +number of cache line allocated in the L2 and the number of modified cache lines +evicted from the L2. This group also output data volume transferred between the +L3 and measured cores L2 caches. Note that this bandwidth also includes data +transfers due to a write allocate load on a store miss in L2. + diff --git a/collectors/likwid/groups/CLX/L3CACHE.txt b/collectors/likwid/groups/CLX/L3CACHE.txt new file mode 100644 index 0000000..bc664d1 --- /dev/null +++ b/collectors/likwid/groups/CLX/L3CACHE.txt @@ -0,0 +1,35 @@ +SHORT L3 cache miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 MEM_LOAD_RETIRED_L3_HIT +PMC1 MEM_LOAD_RETIRED_L3_MISS +PMC2 UOPS_RETIRED_ALL + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L3 request rate (PMC0+PMC1)/PMC2 +L3 miss rate PMC1/PMC2 +L3 miss ratio PMC1/(PMC0+PMC1) + +LONG +Formulas: +L3 request rate = (MEM_LOAD_RETIRED_L3_HIT+MEM_LOAD_RETIRED_L3_MISS)/UOPS_RETIRED_ALL +L3 miss rate = MEM_LOAD_UOPS_RETIRED_L3_MISS/UOPS_RETIRED_ALL +L3 miss ratio = MEM_LOAD_UOPS_RETIRED_L3_MISS/(MEM_LOAD_RETIRED_L3_HIT+MEM_LOAD_RETIRED_L3_MISS) +- +This group measures the locality of your data accesses with regard to the +L3 cache. L3 request rate tells you how data intensive your code is +or how many data accesses you have on average per instruction. +The L3 miss rate gives a measure how often it was necessary to get +cache lines from memory. And finally L3 miss ratio tells you how many of your +memory references required a cache line to be loaded from a higher level. +While the data cache miss rate might be given by your algorithm you should +try to get data cache miss ratio as low as possible by increasing your cache reuse. + + diff --git a/collectors/likwid/groups/CLX/MEM.txt b/collectors/likwid/groups/CLX/MEM.txt new file mode 100644 index 0000000..3d50ecb --- /dev/null +++ b/collectors/likwid/groups/CLX/MEM.txt @@ -0,0 +1,48 @@ +SHORT Main memory bandwidth in MBytes/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +MBOX0C0 CAS_COUNT_RD +MBOX0C1 CAS_COUNT_WR +MBOX1C0 CAS_COUNT_RD +MBOX1C1 CAS_COUNT_WR +MBOX2C0 CAS_COUNT_RD +MBOX2C1 CAS_COUNT_WR +MBOX3C0 CAS_COUNT_RD +MBOX3C1 CAS_COUNT_WR +MBOX4C0 CAS_COUNT_RD +MBOX4C1 CAS_COUNT_WR +MBOX5C0 CAS_COUNT_RD +MBOX5C1 CAS_COUNT_WR + + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Memory read bandwidth [MBytes/s] 1.0E-06*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0)*64.0/time +Memory read data volume [GBytes] 1.0E-09*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0)*64.0 +Memory write bandwidth [MBytes/s] 1.0E-06*(MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1)*64.0/time +Memory write data volume [GBytes] 1.0E-09*(MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1)*64.0 +Memory bandwidth [MBytes/s] 1.0E-06*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1)*64.0/time +Memory data volume [GBytes] 1.0E-09*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1)*64.0 + +LONG +Formulas: +Memory read bandwidth [MBytes/s] = 1.0E-06*(SUM(MBOXxC0))*64.0/runtime +Memory read data volume [GBytes] = 1.0E-09*(SUM(MBOXxC0))*64.0 +Memory write bandwidth [MBytes/s] = 1.0E-06*(SUM(MBOXxC1))*64.0/runtime +Memory write data volume [GBytes] = 1.0E-09*(SUM(MBOXxC1))*64.0 +Memory bandwidth [MBytes/s] = 1.0E-06*(SUM(MBOXxC0)+SUM(MBOXxC1))*64.0/runtime +Memory data volume [GBytes] = 1.0E-09*(SUM(MBOXxC0)+SUM(MBOXxC1))*64.0 +- +Profiling group to measure memory bandwidth drawn by all cores of a socket. +Since this group is based on Uncore events it is only possible to measure on a +per socket base. Some of the counters may not be available on your system. +Also outputs total data volume transferred from main memory. +The same metrics are provided by the HA group. + diff --git a/collectors/likwid/groups/CLX/MEM_DP.txt b/collectors/likwid/groups/CLX/MEM_DP.txt new file mode 100644 index 0000000..68e8684 --- /dev/null +++ b/collectors/likwid/groups/CLX/MEM_DP.txt @@ -0,0 +1,70 @@ +SHORT Overview of arithmetic and main memory performance + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PWR0 PWR_PKG_ENERGY +PWR3 PWR_DRAM_ENERGY +PMC0 FP_ARITH_INST_RETIRED_128B_PACKED_DOUBLE +PMC1 FP_ARITH_INST_RETIRED_SCALAR_DOUBLE +PMC2 FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE +PMC3 FP_ARITH_INST_RETIRED_512B_PACKED_DOUBLE +MBOX0C0 CAS_COUNT_RD +MBOX0C1 CAS_COUNT_WR +MBOX1C0 CAS_COUNT_RD +MBOX1C1 CAS_COUNT_WR +MBOX2C0 CAS_COUNT_RD +MBOX2C1 CAS_COUNT_WR +MBOX3C0 CAS_COUNT_RD +MBOX3C1 CAS_COUNT_WR +MBOX4C0 CAS_COUNT_RD +MBOX4C1 CAS_COUNT_WR +MBOX5C0 CAS_COUNT_RD +MBOX5C1 CAS_COUNT_WR + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Energy [J] PWR0 +Power [W] PWR0/time +Energy DRAM [J] PWR3 +Power DRAM [W] PWR3/time +DP [MFLOP/s] 1.0E-06*(PMC0*2.0+PMC1+PMC2*4.0+PMC3*8.0)/time +AVX DP [MFLOP/s] 1.0E-06*(PMC2*4.0+PMC3*8.0)/time +Packed [MUOPS/s] 1.0E-06*(PMC0+PMC2+PMC3)/time +Scalar [MUOPS/s] 1.0E-06*PMC1/time +Memory read bandwidth [MBytes/s] 1.0E-06*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0)*64.0/time +Memory read data volume [GBytes] 1.0E-09*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0)*64.0 +Memory write bandwidth [MBytes/s] 1.0E-06*(MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1)*64.0/time +Memory write data volume [GBytes] 1.0E-09*(MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1)*64.0 +Memory bandwidth [MBytes/s] 1.0E-06*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1)*64.0/time +Memory data volume [GBytes] 1.0E-09*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1)*64.0 +Operational intensity (PMC0*2.0+PMC1+PMC2*4.0+PMC3*8.0)/((MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1)*64.0) + +LONG +Formulas: +Power [W] = PWR_PKG_ENERGY/runtime +Power DRAM [W] = PWR_DRAM_ENERGY/runtime +DP [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_128B_PACKED_DOUBLE*2+FP_ARITH_INST_RETIRED_SCALAR_DOUBLE+FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE*4+FP_ARITH_INST_RETIRED_512B_PACKED_DOUBLE*8)/runtime +AVX DP [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE*4+FP_ARITH_INST_RETIRED_512B_PACKED_DOUBLE*8)/runtime +Packed [MUOPS/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_128B_PACKED_DOUBLE+FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE+FP_ARITH_INST_RETIRED_512B_PACKED_DOUBLE)/runtime +Scalar [MUOPS/s] = 1.0E-06*FP_ARITH_INST_RETIRED_SCALAR_DOUBLE/runtime +Memory read bandwidth [MBytes/s] = 1.0E-06*(SUM(CAS_COUNT_RD))*64.0/runtime +Memory read data volume [GBytes] = 1.0E-09*(SUM(CAS_COUNT_RD))*64.0 +Memory write bandwidth [MBytes/s] = 1.0E-06*(SUM(CAS_COUNT_WR))*64.0/runtime +Memory write data volume [GBytes] = 1.0E-09*(SUM(CAS_COUNT_WR))*64.0 +Memory bandwidth [MBytes/s] = 1.0E-06*(SUM(CAS_COUNT_RD)+SUM(CAS_COUNT_WR))*64.0/runtime +Memory data volume [GBytes] = 1.0E-09*(SUM(CAS_COUNT_RD)+SUM(CAS_COUNT_WR))*64.0 +Operational intensity = (FP_ARITH_INST_RETIRED_128B_PACKED_DOUBLE*2+FP_ARITH_INST_RETIRED_SCALAR_DOUBLE+FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE*4+FP_ARITH_INST_RETIRED_512B_PACKED_DOUBLE*8)/(SUM(CAS_COUNT_RD)+SUM(CAS_COUNT_WR))*64.0) +-- +Profiling group to measure memory bandwidth drawn by all cores of a socket. +Since this group is based on Uncore events it is only possible to measure on +a per socket base. Also outputs total data volume transferred from main memory. +SSE scalar and packed double precision FLOP rates. Also reports on packed AVX +32b instructions. +The operational intensity is calculated using the FP values of the cores and the +memory data volume of the whole socket. The actual operational intensity for +multiple CPUs can be found in the statistics table in the Sum column. diff --git a/collectors/likwid/groups/CLX/MEM_SP.txt b/collectors/likwid/groups/CLX/MEM_SP.txt new file mode 100644 index 0000000..73452f2 --- /dev/null +++ b/collectors/likwid/groups/CLX/MEM_SP.txt @@ -0,0 +1,70 @@ +SHORT Overview of arithmetic and main memory performance + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PWR0 PWR_PKG_ENERGY +PWR3 PWR_DRAM_ENERGY +PMC0 FP_ARITH_INST_RETIRED_128B_PACKED_SINGLE +PMC1 FP_ARITH_INST_RETIRED_SCALAR_SINGLE +PMC2 FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE +PMC3 FP_ARITH_INST_RETIRED_512B_PACKED_SINGLE +MBOX0C0 CAS_COUNT_RD +MBOX0C1 CAS_COUNT_WR +MBOX1C0 CAS_COUNT_RD +MBOX1C1 CAS_COUNT_WR +MBOX2C0 CAS_COUNT_RD +MBOX2C1 CAS_COUNT_WR +MBOX3C0 CAS_COUNT_RD +MBOX3C1 CAS_COUNT_WR +MBOX4C0 CAS_COUNT_RD +MBOX4C1 CAS_COUNT_WR +MBOX5C0 CAS_COUNT_RD +MBOX5C1 CAS_COUNT_WR + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Energy [J] PWR0 +Power [W] PWR0/time +Energy DRAM [J] PWR3 +Power DRAM [W] PWR3/time +SP [MFLOP/s] 1.0E-06*(PMC0*4.0+PMC1+PMC2*8.0+PMC3*16.0)/time +AVX SP [MFLOP/s] 1.0E-06*(PMC2*8.0+PMC3*16.0)/time +Packed [MUOPS/s] 1.0E-06*(PMC0+PMC2+PMC3)/time +Scalar [MUOPS/s] 1.0E-06*PMC1/time +Memory read bandwidth [MBytes/s] 1.0E-06*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0)*64.0/time +Memory read data volume [GBytes] 1.0E-09*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0)*64.0 +Memory write bandwidth [MBytes/s] 1.0E-06*(MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1)*64.0/time +Memory write data volume [GBytes] 1.0E-09*(MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1)*64.0 +Memory bandwidth [MBytes/s] 1.0E-06*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1)*64.0/time +Memory data volume [GBytes] 1.0E-09*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1)*64.0 +Operational intensity (PMC0*4.0+PMC1+PMC2*8.0+PMC3*16.0)/((MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1)*64.0) + +LONG +Formulas: +Power [W] = PWR_PKG_ENERGY/runtime +Power DRAM [W] = PWR_DRAM_ENERGY/runtime +SP [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_128B_PACKED_SINGLE*4+FP_ARITH_INST_RETIRED_SCALAR_SINGLE+FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE*8+FP_ARITH_INST_RETIRED_512B_PACKED_SINGLE*16)/runtime +AVX SP [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE*8+FP_ARITH_INST_RETIRED_512B_PACKED_SINGLE*16)/runtime +Packed [MUOPS/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_128B_PACKED_SINGLE+FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE+FP_ARITH_INST_RETIRED_512B_PACKED_SINGLE)/runtime +Scalar [MUOPS/s] = 1.0E-06*FP_ARITH_INST_RETIRED_SCALAR_SINGLE/runtime +Memory read bandwidth [MBytes/s] = 1.0E-06*(SUM(CAS_COUNT_RD))*64.0/runtime +Memory read data volume [GBytes] = 1.0E-09*(SUM(CAS_COUNT_RD))*64.0 +Memory write bandwidth [MBytes/s] = 1.0E-06*(SUM(CAS_COUNT_WR))*64.0/runtime +Memory write data volume [GBytes] = 1.0E-09*(SUM(CAS_COUNT_WR))*64.0 +Memory bandwidth [MBytes/s] = 1.0E-06*(SUM(CAS_COUNT_RD)+SUM(CAS_COUNT_WR))*64.0/runtime +Memory data volume [GBytes] = 1.0E-09*(SUM(CAS_COUNT_RD)+SUM(CAS_COUNT_WR))*64.0 +Operational intensity = (FP_ARITH_INST_RETIRED_128B_PACKED_SINGLE*4+FP_ARITH_INST_RETIRED_SCALAR_SINGLE+FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE*8+FP_ARITH_INST_RETIRED_512B_PACKED_SINGLE*16)/(SUM(CAS_COUNT_RD)+SUM(CAS_COUNT_WR))*64.0) +-- +Profiling group to measure memory bandwidth drawn by all cores of a socket. +Since this group is based on Uncore events it is only possible to measure on +a per socket base. Also outputs total data volume transferred from main memory. +SSE scalar and packed single precision FLOP rates. Also reports on packed AVX +32b instructions. +The operational intensity is calculated using the FP values of the cores and the +memory data volume of the whole socket. The actual operational intensity for +multiple CPUs can be found in the statistics table in the Sum column. diff --git a/collectors/likwid/groups/CLX/PMM.txt b/collectors/likwid/groups/CLX/PMM.txt new file mode 100644 index 0000000..dbaa6ab --- /dev/null +++ b/collectors/likwid/groups/CLX/PMM.txt @@ -0,0 +1,46 @@ +SHORT Intel Optance DC bandwidth in MBytes/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +MBOX0C0 PMM_CMD1_RD +MBOX0C1 PMM_CMD1_WR +MBOX1C0 PMM_CMD1_RD +MBOX1C1 PMM_CMD1_WR +MBOX2C0 PMM_CMD1_RD +MBOX2C1 PMM_CMD1_WR +MBOX3C0 PMM_CMD1_RD +MBOX3C1 PMM_CMD1_WR +MBOX4C0 PMM_CMD1_RD +MBOX4C1 PMM_CMD1_WR +MBOX5C0 PMM_CMD1_RD +MBOX5C1 PMM_CMD1_WR + + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +PMM read bandwidth [MBytes/s] 1.0E-06*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0)*64.0/time +PMM read data volume [GBytes] 1.0E-09*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0)*64.0 +PMM write bandwidth [MBytes/s] 1.0E-06*(MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1)*64.0/time +PMM write data volume [GBytes] 1.0E-09*(MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1)*64.0 +PMM bandwidth [MBytes/s] 1.0E-06*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1)*64.0/time +PMM data volume [GBytes] 1.0E-09*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1)*64.0 + +LONG +Formulas: +PMM read bandwidth [MBytes/s] = 1.0E-06*(SUM(MBOXxC0))*64.0/runtime +PMM read data volume [GBytes] = 1.0E-09*(SUM(MBOXxC0))*64.0 +PMM write bandwidth [MBytes/s] = 1.0E-06*(SUM(MBOXxC1))*64.0/runtime +PMM write data volume [GBytes] = 1.0E-09*(SUM(MBOXxC1))*64.0 +PMM bandwidth [MBytes/s] = 1.0E-06*(SUM(MBOXxC0)+SUM(MBOXxC1))*64.0/runtime +PMM data volume [GBytes] = 1.0E-09*(SUM(MBOXxC0)+SUM(MBOXxC1))*64.0 +- +Profiling group to measure data rate and volume for accesses to Intel Optane DC +persistent memory. The Intel Optance DC devices are handled by the memory +controllers but require different events. + diff --git a/collectors/likwid/groups/CLX/TLB_DATA.txt b/collectors/likwid/groups/CLX/TLB_DATA.txt new file mode 100644 index 0000000..10ee5e1 --- /dev/null +++ b/collectors/likwid/groups/CLX/TLB_DATA.txt @@ -0,0 +1,35 @@ +SHORT L2 data TLB miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 DTLB_LOAD_MISSES_CAUSES_A_WALK +PMC1 DTLB_STORE_MISSES_CAUSES_A_WALK +PMC2 DTLB_LOAD_MISSES_WALK_ACTIVE +PMC3 DTLB_STORE_MISSES_WALK_ACTIVE + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L1 DTLB load misses PMC0 +L1 DTLB load miss rate PMC0/FIXC0 +L1 DTLB load miss duration [Cyc] PMC2/PMC0 +L1 DTLB store misses PMC1 +L1 DTLB store miss rate PMC1/FIXC0 +L1 DTLB store miss duration [Cyc] PMC3/PMC1 + +LONG +Formulas: +L1 DTLB load misses = DTLB_LOAD_MISSES_CAUSES_A_WALK +L1 DTLB load miss rate = DTLB_LOAD_MISSES_CAUSES_A_WALK / INSTR_RETIRED_ANY +L1 DTLB load miss duration [Cyc] = DTLB_LOAD_MISSES_WALK_ACTIVE / DTLB_LOAD_MISSES_CAUSES_A_WALK +L1 DTLB store misses = DTLB_STORE_MISSES_CAUSES_A_WALK +L1 DTLB store miss rate = DTLB_STORE_MISSES_CAUSES_A_WALK / INSTR_RETIRED_ANY +L1 DTLB store miss duration [Cyc] = DTLB_STORE_MISSES_WALK_ACTIVE / DTLB_STORE_MISSES_CAUSES_A_WALK +- +The DTLB load and store miss rates gives a measure how often a TLB miss occurred +per instruction. The duration measures the time in cycles how long a walk did take. + diff --git a/collectors/likwid/groups/CLX/TLB_INSTR.txt b/collectors/likwid/groups/CLX/TLB_INSTR.txt new file mode 100644 index 0000000..9bc65a7 --- /dev/null +++ b/collectors/likwid/groups/CLX/TLB_INSTR.txt @@ -0,0 +1,28 @@ +SHORT L1 Instruction TLB miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 ITLB_MISSES_CAUSES_A_WALK +PMC1 ITLB_MISSES_WALK_ACTIVE + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L1 ITLB misses PMC0 +L1 ITLB miss rate PMC0/FIXC0 +L1 ITLB miss duration [Cyc] PMC1/PMC0 + + +LONG +Formulas: +L1 ITLB misses = ITLB_MISSES_CAUSES_A_WALK +L1 ITLB miss rate = ITLB_MISSES_CAUSES_A_WALK / INSTR_RETIRED_ANY +L1 ITLB miss duration [Cyc] = ITLB_MISSES_WALK_ACTIVE / ITLB_MISSES_CAUSES_A_WALK +- +The ITLB miss rates gives a measure how often a TLB miss occurred +per instruction. The duration measures the time in cycles how long a walk did take. + diff --git a/collectors/likwid/groups/CLX/TMA.txt b/collectors/likwid/groups/CLX/TMA.txt new file mode 100644 index 0000000..afb4126 --- /dev/null +++ b/collectors/likwid/groups/CLX/TMA.txt @@ -0,0 +1,48 @@ +SHORT Top down cycle allocation + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 UOPS_ISSUED_ANY +PMC1 UOPS_RETIRED_RETIRE_SLOTS +PMC2 IDQ_UOPS_NOT_DELIVERED_CORE +PMC3 INT_MISC_RECOVERY_CYCLES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +IPC FIXC0/FIXC1 +Total Slots 4*FIXC1 +Slots Retired PMC1 +Fetch Bubbles PMC2 +Recovery Bubbles 4*PMC3 +Front End [%] PMC2/(4*FIXC1)*100 +Speculation [%] (PMC0-PMC1+(4*PMC3))/(4*FIXC1)*100 +Retiring [%] PMC1/(4*FIXC1)*100 +Back End [%] (1-((PMC2+PMC0+(4*PMC3))/(4*FIXC1)))*100 + +LONG +Formulas: +Total Slots = 4*CPU_CLK_UNHALTED_CORE +Slots Retired = UOPS_RETIRED_RETIRE_SLOTS +Fetch Bubbles = IDQ_UOPS_NOT_DELIVERED_CORE +Recovery Bubbles = 4*INT_MISC_RECOVERY_CYCLES +Front End [%] = IDQ_UOPS_NOT_DELIVERED_CORE/(4*CPU_CLK_UNHALTED_CORE)*100 +Speculation [%] = (UOPS_ISSUED_ANY-UOPS_RETIRED_RETIRE_SLOTS+(4*INT_MISC_RECOVERY_CYCLES))/(4*CPU_CLK_UNHALTED_CORE)*100 +Retiring [%] = UOPS_RETIRED_RETIRE_SLOTS/(4*CPU_CLK_UNHALTED_CORE)*100 +Back End [%] = (1-((IDQ_UOPS_NOT_DELIVERED_CORE+UOPS_ISSUED_ANY+(4*INT_MISC_RECOVERY_CYCLES))/(4*CPU_CLK_UNHALTED_CORE)))*100 +-- +This performance group measures cycles to determine percentage of time spent in +front end, back end, retiring and speculation. These metrics are published and +verified by Intel. Further information: +Webpage describing Top-Down Method and its usage in Intel vTune: +https://software.intel.com/en-us/vtune-amplifier-help-tuning-applications-using-a-top-down-microarchitecture-analysis-method +Paper by Yasin Ahmad: +https://sites.google.com/site/analysismethods/yasin-pubs/TopDown-Yasin-ISPASS14.pdf?attredirects=0 +Slides by Yasin Ahmad: +http://www.cs.technion.ac.il/~erangi/TMA_using_Linux_perf__Ahmad_Yasin.pdf +The performance group was originally published here: +http://perf.mvermeulen.com/2018/04/14/top-down-performance-counter-analysis-part-1-likwid/ diff --git a/collectors/likwid/groups/CLX/UOPS_EXEC.txt b/collectors/likwid/groups/CLX/UOPS_EXEC.txt new file mode 100644 index 0000000..7042df7 --- /dev/null +++ b/collectors/likwid/groups/CLX/UOPS_EXEC.txt @@ -0,0 +1,31 @@ +SHORT UOPs execution + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 UOPS_EXECUTED_USED_CYCLES +PMC1 UOPS_EXECUTED_STALL_CYCLES +PMC2 CPU_CLOCK_UNHALTED_TOTAL_CYCLES +PMC3:EDGEDETECT UOPS_EXECUTED_STALL_CYCLES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Used cycles ratio [%] 100*PMC0/PMC2 +Unused cycles ratio [%] 100*PMC1/PMC2 +Avg stall duration [cycles] PMC1/PMC3:EDGEDETECT + + +LONG +Formulas: +Used cycles ratio [%] = 100*UOPS_EXECUTED_USED_CYCLES/CPU_CLK_UNHALTED_CORE +Unused cycles ratio [%] = 100*UOPS_EXECUTED_STALL_CYCLES/CPU_CLK_UNHALTED_CORE +Avg stall duration [cycles] = UOPS_EXECUTED_STALL_CYCLES/UOPS_EXECUTED_STALL_CYCLES:EDGEDETECT +- +This performance group returns the ratios of used and unused cycles regarding +the execution stage in the pipeline. Used cycles are all cycles where uOPs are +executed while unused cycles refer to pipeline stalls. Moreover, the group +calculates the average stall duration in cycles. diff --git a/collectors/likwid/groups/CLX/UOPS_ISSUE.txt b/collectors/likwid/groups/CLX/UOPS_ISSUE.txt new file mode 100644 index 0000000..9aac923 --- /dev/null +++ b/collectors/likwid/groups/CLX/UOPS_ISSUE.txt @@ -0,0 +1,31 @@ +SHORT UOPs issueing + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 UOPS_ISSUED_USED_CYCLES +PMC1 UOPS_ISSUED_STALL_CYCLES +PMC2 CPU_CLOCK_UNHALTED_TOTAL_CYCLES +PMC3:EDGEDETECT UOPS_ISSUED_STALL_CYCLES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Used cycles ratio [%] 100*PMC0/PMC2 +Unused cycles ratio [%] 100*PMC1/PMC2 +Avg stall duration [cycles] PMC1/PMC3:EDGEDETECT + + +LONG +Formulas: +Used cycles ratio [%] = 100*UOPS_ISSUED_USED_CYCLES/CPU_CLK_UNHALTED_CORE +Unused cycles ratio [%] = 100*UOPS_ISSUED_STALL_CYCLES/CPU_CLK_UNHALTED_CORE +Avg stall duration [cycles] = UOPS_ISSUED_STALL_CYCLES/UOPS_ISSUED_STALL_CYCLES:EDGEDETECT +- +This performance group returns the ratios of used and unused cycles regarding +the issue stage in the pipeline. Used cycles are all cycles where uOPs are +issued while unused cycles refer to pipeline stalls. Moreover, the group +calculates the average stall duration in cycles. diff --git a/collectors/likwid/groups/CLX/UOPS_RETIRE.txt b/collectors/likwid/groups/CLX/UOPS_RETIRE.txt new file mode 100644 index 0000000..0f37585 --- /dev/null +++ b/collectors/likwid/groups/CLX/UOPS_RETIRE.txt @@ -0,0 +1,31 @@ +SHORT UOPs retirement + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 UOPS_RETIRED_USED_CYCLES +PMC1 UOPS_RETIRED_STALL_CYCLES +PMC2 CPU_CLOCK_UNHALTED_TOTAL_CYCLES +PMC3:EDGEDETECT UOPS_RETIRED_STALL_CYCLES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Used cycles ratio [%] 100*PMC0/PMC2 +Unused cycles ratio [%] 100*PMC1/PMC2 +Avg stall duration [cycles] PMC1/PMC3:EDGEDETECT + + +LONG +Formulas: +Used cycles ratio [%] = 100*UOPS_RETIRED_USED_CYCLES/CPU_CLK_UNHALTED_CORE +Unused cycles ratio [%] = 100*UOPS_RETIRED_STALL_CYCLES/CPU_CLK_UNHALTED_CORE +Avg stall duration [cycles] = UOPS_RETIRED_STALL_CYCLES/UOPS_RETIRED_STALL_CYCLES:EDGEDETECT +- +This performance group returns the ratios of used and unused cycles regarding +the retirement stage in the pipeline (re-order buffer). Used cycles are all +cycles where uOPs are retired while unused cycles refer to pipeline stalls. +Moreover, the group calculates the average stall duration in cycles. diff --git a/collectors/likwid/groups/CLX/UPI.txt b/collectors/likwid/groups/CLX/UPI.txt new file mode 100644 index 0000000..2a4c44f --- /dev/null +++ b/collectors/likwid/groups/CLX/UPI.txt @@ -0,0 +1,42 @@ +SHORT UPI data traffic + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +SBOX0C0 TXL_FLITS_ALL_DATA +SBOX0C1 RXL_FLITS_ALL_DATA +SBOX1C0 TXL_FLITS_ALL_DATA +SBOX1C1 RXL_FLITS_ALL_DATA +SBOX2C0 TXL_FLITS_ALL_DATA +SBOX2C1 RXL_FLITS_ALL_DATA + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Received data bandwidth [MByte/s] 1.0E-06*((SBOX0C1+SBOX1C1+SBOX2C1)/9.0)*64.0/time +Received data volume [GByte] 1.0E-09*((SBOX0C1+SBOX1C1+SBOX2C1)/9.0)*64.0 +Sent data bandwidth [MByte/s] 1.0E-06*((SBOX0C0+SBOX1C0+SBOX2C0)/9.0)*64.0/time +Sent data volume [GByte] 1.0E-09*((SBOX0C0+SBOX1C0+SBOX2C0)/9.0)*64.0 +Total data bandwidth [MByte/s] 1.0E-06*((SBOX0C0+SBOX1C0+SBOX2C0+SBOX0C1+SBOX1C1+SBOX2C1)/9.0)*64.0/time +Total data volume [GByte] 1.0E-09*((SBOX0C0+SBOX1C0+SBOX2C0+SBOX0C1+SBOX1C1+SBOX2C1)/9.0)*64.0 + + +LONG +Formulas: +Received data bandwidth [MByte/s] = 1.0E-06*(SUM(RXL_FLITS_ALL_DATA)/9.0)*64.0/runtime +Received data volume [GByte] = 1.0E-09*(SUM(RXL_FLITS_ALL_DATA)/9.0)*64.0 +Sent data bandwidth [MByte/s] = 1.0E-06*(SUM(TXL_FLITS_ALL_DATA)/9.0)*64.0/time +Sent data volume [GByte] = 1.0E-09*(SUM(TXL_FLITS_ALL_DATA)/9.0)*64.0 +Total data bandwidth [MByte/s] = 1.0E-06*((SUM(RXL_FLITS_ALL_DATA)+SUM(TXL_FLITS_ALL_DATA))/9.0)*64.0/time +Total data volume [GByte] = 1.0E-09*((SUM(RXL_FLITS_ALL_DATA)+SUM(TXL_FLITS_ALL_DATA))/9.0)*64.0 +-- +This group measures the data traffic on the UPI (socket interconnect). The group +measures all filled data slots (9 slots per 64 Byte data transfer), that's why +the count needs to be divided by 9. These 9 data chunks are not transferred in +a single flit but there is one flit for the header and three flits for the data. +The metrics show higher values as expected because the events count also +different transfers which include data. diff --git a/collectors/likwid/groups/ICL/BRANCH.txt b/collectors/likwid/groups/ICL/BRANCH.txt new file mode 100644 index 0000000..b8d41b2 --- /dev/null +++ b/collectors/likwid/groups/ICL/BRANCH.txt @@ -0,0 +1,31 @@ +SHORT Branch prediction miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 BR_INST_RETIRED_ALL_BRANCHES +PMC1 BR_MISP_RETIRED_ALL_BRANCHES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Branch rate PMC0/FIXC0 +Branch misprediction rate PMC1/FIXC0 +Branch misprediction ratio PMC1/PMC0 +Instructions per branch FIXC0/PMC0 + +LONG +Formulas: +Branch rate = BR_INST_RETIRED_ALL_BRANCHES/INSTR_RETIRED_ANY +Branch misprediction rate = BR_MISP_RETIRED_ALL_BRANCHES/INSTR_RETIRED_ANY +Branch misprediction ratio = BR_MISP_RETIRED_ALL_BRANCHES/BR_INST_RETIRED_ALL_BRANCHES +Instructions per branch = INSTR_RETIRED_ANY/BR_INST_RETIRED_ALL_BRANCHES +- +The rates state how often on average a branch or a mispredicted branch occurred +per instruction retired in total. The branch misprediction ratio sets directly +into relation what ratio of all branch instruction where mispredicted. +Instructions per branch is 1/branch rate. + diff --git a/collectors/likwid/groups/ICL/DATA.txt b/collectors/likwid/groups/ICL/DATA.txt new file mode 100644 index 0000000..4e6e938 --- /dev/null +++ b/collectors/likwid/groups/ICL/DATA.txt @@ -0,0 +1,22 @@ +SHORT Load to store ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 MEM_INST_RETIRED_ALL_LOADS +PMC1 MEM_INST_RETIRED_ALL_STORES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Load to store ratio PMC0/PMC1 + +LONG +Formulas: +Load to store ratio = MEM_INST_RETIRED_ALL_LOADS/MEM_INST_RETIRED_ALL_STORES +- +This is a metric to determine your load to store ratio. + diff --git a/collectors/likwid/groups/ICL/DIVIDE.txt b/collectors/likwid/groups/ICL/DIVIDE.txt new file mode 100644 index 0000000..40b4ab6 --- /dev/null +++ b/collectors/likwid/groups/ICL/DIVIDE.txt @@ -0,0 +1,24 @@ +SHORT Divide unit information + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 ARITH_DIVIDER_COUNT +PMC1 ARITH_DIVIDER_ACTIVE + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Number of divide ops PMC0 +Avg. divide unit usage duration PMC1/PMC0 + +LONG +Formulas: +Number of divide ops = ARITH_DIVIDER_COUNT +Avg. divide unit usage duration = ARITH_DIVIDER_ACTIVE/ARITH_DIVIDER_COUNT +- +This performance group measures the average latency of divide operations diff --git a/collectors/likwid/groups/ICL/ENERGY.txt b/collectors/likwid/groups/ICL/ENERGY.txt new file mode 100644 index 0000000..fe7829f --- /dev/null +++ b/collectors/likwid/groups/ICL/ENERGY.txt @@ -0,0 +1,35 @@ +SHORT Power and Energy consumption + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +TMP0 TEMP_CORE +PWR0 PWR_PKG_ENERGY +PWR1 PWR_PP0_ENERGY +PWR3 PWR_DRAM_ENERGY + + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Temperature [C] TMP0 +Energy [J] PWR0 +Power [W] PWR0/time +Energy PP0 [J] PWR1 +Power PP0 [W] PWR1/time +Energy DRAM [J] PWR3 +Power DRAM [W] PWR3/time + +LONG +Formulas: +Power = PWR_PKG_ENERGY / time +Power PP0 = PWR_PP0_ENERGY / time +Power DRAM = PWR_DRAM_ENERGY / time +- +Broadwell implements the new RAPL interface. This interface enables to +monitor the consumed energy on the package (socket) and DRAM level. + diff --git a/collectors/likwid/groups/ICL/FLOPS_AVX.txt b/collectors/likwid/groups/ICL/FLOPS_AVX.txt new file mode 100644 index 0000000..e44a913 --- /dev/null +++ b/collectors/likwid/groups/ICL/FLOPS_AVX.txt @@ -0,0 +1,25 @@ +SHORT Packed AVX MFLOP/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE +PMC1 FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE +PMC2 FP_ARITH_INST_RETIRED_512B_PACKED_SINGLE +PMC3 FP_ARITH_INST_RETIRED_512B_PACKED_DOUBLE + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Packed SP [MFLOP/s] 1.0E-06*(PMC0*8.0+PMC2*16.0)/time +Packed DP [MFLOP/s] 1.0E-06*(PMC1*4.0+PMC3*8.0)/time + +LONG +Formulas: +Packed SP [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE*8+FP_ARITH_INST_RETIRED_512B_PACKED_SINGLE*16)/runtime +Packed DP [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE*4+FP_ARITH_INST_RETIRED_512B_PACKED_DOUBLE*8)/runtime +- +Packed 32b AVX FLOPs rates. diff --git a/collectors/likwid/groups/ICL/FLOPS_DP.txt b/collectors/likwid/groups/ICL/FLOPS_DP.txt new file mode 100644 index 0000000..177cff2 --- /dev/null +++ b/collectors/likwid/groups/ICL/FLOPS_DP.txt @@ -0,0 +1,34 @@ +SHORT Double Precision MFLOP/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 FP_ARITH_INST_RETIRED_128B_PACKED_DOUBLE +PMC1 FP_ARITH_INST_RETIRED_SCALAR_DOUBLE +PMC2 FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE +PMC3 FP_ARITH_INST_RETIRED_512B_PACKED_DOUBLE + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +DP [MFLOP/s] 1.0E-06*(PMC0*2.0+PMC1+PMC2*4.0+PMC3*8.0)/time +AVX DP [MFLOP/s] 1.0E-06*(PMC2*4.0+PMC3*8.0)/time +AVX512 DP [MFLOP/s] 1.0E-06*(PMC3*8.0)/time +Packed [MUOPS/s] 1.0E-06*(PMC0+PMC2+PMC3)/time +Scalar [MUOPS/s] 1.0E-06*PMC1/time +Vectorization ratio 100*(PMC0+PMC2+PMC3)/(PMC0+PMC1+PMC2+PMC3) + +LONG +Formulas: +DP [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_128B_PACKED_DOUBLE*2+FP_ARITH_INST_RETIRED_SCALAR_DOUBLE+FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE*4+FP_ARITH_INST_RETIRED_512B_PACKED_DOUBLE*8)/runtime +AVX DP [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE*4+FP_ARITH_INST_RETIRED_512B_PACKED_DOUBLE*8)/runtime +AVX512 DP [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_512B_PACKED_DOUBLE*8)/runtime +Packed [MUOPS/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_128B_PACKED_DOUBLE+FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE+FP_ARITH_INST_RETIRED_512B_PACKED_DOUBLE)/runtime +Scalar [MUOPS/s] = 1.0E-06*FP_ARITH_INST_RETIRED_SCALAR_DOUBLE/runtime +Vectorization ratio = 100*(FP_ARITH_INST_RETIRED_128B_PACKED_DOUBLE+FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE+FP_ARITH_INST_RETIRED_512B_PACKED_DOUBLE)/(FP_ARITH_INST_RETIRED_SCALAR_DOUBLE+FP_ARITH_INST_RETIRED_128B_PACKED_DOUBLE+FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE+FP_ARITH_INST_RETIRED_512B_PACKED_DOUBLE) +- +SSE scalar and packed double precision FLOP rates. + diff --git a/collectors/likwid/groups/ICL/FLOPS_SP.txt b/collectors/likwid/groups/ICL/FLOPS_SP.txt new file mode 100644 index 0000000..01d98c2 --- /dev/null +++ b/collectors/likwid/groups/ICL/FLOPS_SP.txt @@ -0,0 +1,34 @@ +SHORT Single Precision MFLOP/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 FP_ARITH_INST_RETIRED_128B_PACKED_SINGLE +PMC1 FP_ARITH_INST_RETIRED_SCALAR_SINGLE +PMC2 FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE +PMC3 FP_ARITH_INST_RETIRED_512B_PACKED_SINGLE + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +SP [MFLOP/s] 1.0E-06*(PMC0*4.0+PMC1+PMC2*8.0+PMC3*16.0)/time +AVX SP [MFLOP/s] 1.0E-06*(PMC2*8.0+PMC3*16.0)/time +AVX512 SP [MFLOP/s] 1.0E-06*(PMC3*16.0)/time +Packed [MUOPS/s] 1.0E-06*(PMC0+PMC2+PMC3)/time +Scalar [MUOPS/s] 1.0E-06*PMC1/time +Vectorization ratio 100*(PMC0+PMC2+PMC3)/(PMC0+PMC1+PMC2+PMC3) + +LONG +Formulas: +SP [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_128B_PACKED_SINGLE*4+FP_ARITH_INST_RETIRED_SCALAR_SINGLE+FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE*8+FP_ARITH_INST_RETIRED_512B_PACKED_SINGLE*16)/runtime +AVX SP [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE*8+FP_ARITH_INST_RETIRED_512B_PACKED_SINGLE*16)/runtime +AVX512 SP [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_512B_PACKED_SINGLE*16)/runtime +Packed [MUOPS/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_128B_PACKED_SINGLE+FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE+FP_ARITH_INST_RETIRED_512B_PACKED_SINGLE)/runtime +Scalar [MUOPS/s] = 1.0E-06*FP_ARITH_INST_RETIRED_SCALAR_SINGLE/runtime +Vectorization ratio [%] = 100*(FP_ARITH_INST_RETIRED_128B_PACKED_SINGLE+FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE+FP_ARITH_INST_RETIRED_512B_PACKED_SINGLE)/(FP_ARITH_INST_RETIRED_SCALAR_SINGLE+FP_ARITH_INST_RETIRED_128B_PACKED_SINGLE+FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE+FP_ARITH_INST_RETIRED_512B_PACKED_SINGLE) +- +SSE scalar and packed single precision FLOP rates. + diff --git a/collectors/likwid/groups/ICX/BRANCH.txt b/collectors/likwid/groups/ICX/BRANCH.txt new file mode 100644 index 0000000..3eea828 --- /dev/null +++ b/collectors/likwid/groups/ICX/BRANCH.txt @@ -0,0 +1,32 @@ +SHORT Branch prediction miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +FIXC3 TOPDOWN_SLOTS +PMC0 BR_INST_RETIRED_ALL_BRANCHES +PMC1 BR_MISP_RETIRED_ALL_BRANCHES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Branch rate PMC0/FIXC0 +Branch misprediction rate PMC1/FIXC0 +Branch misprediction ratio PMC1/PMC0 +Instructions per branch FIXC0/PMC0 + +LONG +Formulas: +Branch rate = BR_INST_RETIRED_ALL_BRANCHES/INSTR_RETIRED_ANY +Branch misprediction rate = BR_MISP_RETIRED_ALL_BRANCHES/INSTR_RETIRED_ANY +Branch misprediction ratio = BR_MISP_RETIRED_ALL_BRANCHES/BR_INST_RETIRED_ALL_BRANCHES +Instructions per branch = INSTR_RETIRED_ANY/BR_INST_RETIRED_ALL_BRANCHES +- +The rates state how often on average a branch or a mispredicted branch occurred +per instruction retired in total. The branch misprediction ratio sets directly +into relation what ratio of all branch instruction where mispredicted. +Instructions per branch is 1/branch rate. + diff --git a/collectors/likwid/groups/ICX/DATA.txt b/collectors/likwid/groups/ICX/DATA.txt new file mode 100644 index 0000000..ee15427 --- /dev/null +++ b/collectors/likwid/groups/ICX/DATA.txt @@ -0,0 +1,23 @@ +SHORT Load to store ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +FIXC3 TOPDOWN_SLOTS +PMC0 MEM_INST_RETIRED_ALL_LOADS +PMC1 MEM_INST_RETIRED_ALL_STORES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Load to store ratio PMC0/PMC1 + +LONG +Formulas: +Load to store ratio = MEM_INST_RETIRED_ALL_LOADS/MEM_INST_RETIRED_ALL_STORES +- +This is a metric to determine your load to store ratio. + diff --git a/collectors/likwid/groups/ICX/DIVIDE.txt b/collectors/likwid/groups/ICX/DIVIDE.txt new file mode 100644 index 0000000..5e3be16 --- /dev/null +++ b/collectors/likwid/groups/ICX/DIVIDE.txt @@ -0,0 +1,25 @@ +SHORT Divide unit information + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +FIXC3 TOPDOWN_SLOTS +PMC0 ARITH_DIVIDER_COUNT +PMC1 ARITH_DIVIDER_ACTIVE + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Number of divide ops PMC0 +Avg. divide unit usage duration PMC1/PMC0 + +LONG +Formulas: +Number of divide ops = ARITH_DIVIDER_COUNT +Avg. divide unit usage duration = ARITH_DIVIDER_ACTIVE/ARITH_DIVIDER_COUNT +- +This performance group measures the average latency of divide operations diff --git a/collectors/likwid/groups/ICX/FLOPS_AVX.txt b/collectors/likwid/groups/ICX/FLOPS_AVX.txt new file mode 100644 index 0000000..0f41891 --- /dev/null +++ b/collectors/likwid/groups/ICX/FLOPS_AVX.txt @@ -0,0 +1,26 @@ +SHORT Packed AVX MFLOP/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +FIXC3 TOPDOWN_SLOTS +PMC0 FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE +PMC1 FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE +PMC2 FP_ARITH_INST_RETIRED_512B_PACKED_SINGLE +PMC3 FP_ARITH_INST_RETIRED_512B_PACKED_DOUBLE + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Packed SP [MFLOP/s] 1.0E-06*(PMC0*8.0+PMC2*16.0)/time +Packed DP [MFLOP/s] 1.0E-06*(PMC1*4.0+PMC3*8.0)/time + +LONG +Formulas: +Packed SP [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE*8+FP_ARITH_INST_RETIRED_512B_PACKED_SINGLE*16)/runtime +Packed DP [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE*4+FP_ARITH_INST_RETIRED_512B_PACKED_DOUBLE*8)/runtime +- +Packed 32b AVX FLOPs rates. diff --git a/collectors/likwid/groups/ICX/FLOPS_DP.txt b/collectors/likwid/groups/ICX/FLOPS_DP.txt new file mode 100644 index 0000000..64e7d3d --- /dev/null +++ b/collectors/likwid/groups/ICX/FLOPS_DP.txt @@ -0,0 +1,35 @@ +SHORT Double Precision MFLOP/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +FIXC3 TOPDOWN_SLOTS +PMC0 FP_ARITH_INST_RETIRED_128B_PACKED_DOUBLE +PMC1 FP_ARITH_INST_RETIRED_SCALAR_DOUBLE +PMC2 FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE +PMC3 FP_ARITH_INST_RETIRED_512B_PACKED_DOUBLE + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +DP [MFLOP/s] 1.0E-06*(PMC0*2.0+PMC1+PMC2*4.0+PMC3*8.0)/time +AVX DP [MFLOP/s] 1.0E-06*(PMC2*4.0+PMC3*8.0)/time +AVX512 DP [MFLOP/s] 1.0E-06*(PMC3*8.0)/time +Packed [MUOPS/s] 1.0E-06*(PMC0+PMC2+PMC3)/time +Scalar [MUOPS/s] 1.0E-06*PMC1/time +Vectorization ratio 100*(PMC0+PMC2+PMC3)/(PMC0+PMC1+PMC2+PMC3) + +LONG +Formulas: +DP [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_128B_PACKED_DOUBLE*2+FP_ARITH_INST_RETIRED_SCALAR_DOUBLE+FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE*4+FP_ARITH_INST_RETIRED_512B_PACKED_DOUBLE*8)/runtime +AVX DP [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE*4+FP_ARITH_INST_RETIRED_512B_PACKED_DOUBLE*8)/runtime +AVX512 DP [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_512B_PACKED_DOUBLE*8)/runtime +Packed [MUOPS/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_128B_PACKED_DOUBLE+FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE+FP_ARITH_INST_RETIRED_512B_PACKED_DOUBLE)/runtime +Scalar [MUOPS/s] = 1.0E-06*FP_ARITH_INST_RETIRED_SCALAR_DOUBLE/runtime +Vectorization ratio = 100*(FP_ARITH_INST_RETIRED_128B_PACKED_DOUBLE+FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE+FP_ARITH_INST_RETIRED_512B_PACKED_DOUBLE)/(FP_ARITH_INST_RETIRED_SCALAR_DOUBLE+FP_ARITH_INST_RETIRED_128B_PACKED_DOUBLE+FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE+FP_ARITH_INST_RETIRED_512B_PACKED_DOUBLE) +- +SSE scalar and packed double precision FLOP rates. + diff --git a/collectors/likwid/groups/ICX/FLOPS_SP.txt b/collectors/likwid/groups/ICX/FLOPS_SP.txt new file mode 100644 index 0000000..3e6780b --- /dev/null +++ b/collectors/likwid/groups/ICX/FLOPS_SP.txt @@ -0,0 +1,35 @@ +SHORT Single Precision MFLOP/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +FIXC3 TOPDOWN_SLOTS +PMC0 FP_ARITH_INST_RETIRED_128B_PACKED_SINGLE +PMC1 FP_ARITH_INST_RETIRED_SCALAR_SINGLE +PMC2 FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE +PMC3 FP_ARITH_INST_RETIRED_512B_PACKED_SINGLE + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +SP [MFLOP/s] 1.0E-06*(PMC0*4.0+PMC1+PMC2*8.0+PMC3*16.0)/time +AVX SP [MFLOP/s] 1.0E-06*(PMC2*8.0+PMC3*16.0)/time +AVX512 SP [MFLOP/s] 1.0E-06*(PMC3*16.0)/time +Packed [MUOPS/s] 1.0E-06*(PMC0+PMC2+PMC3)/time +Scalar [MUOPS/s] 1.0E-06*PMC1/time +Vectorization ratio 100*(PMC0+PMC2+PMC3)/(PMC0+PMC1+PMC2+PMC3) + +LONG +Formulas: +SP [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_128B_PACKED_SINGLE*4+FP_ARITH_INST_RETIRED_SCALAR_SINGLE+FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE*8+FP_ARITH_INST_RETIRED_512B_PACKED_SINGLE*16)/runtime +AVX SP [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE*8+FP_ARITH_INST_RETIRED_512B_PACKED_SINGLE*16)/runtime +AVX512 SP [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_512B_PACKED_SINGLE*16)/runtime +Packed [MUOPS/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_128B_PACKED_SINGLE+FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE+FP_ARITH_INST_RETIRED_512B_PACKED_SINGLE)/runtime +Scalar [MUOPS/s] = 1.0E-06*FP_ARITH_INST_RETIRED_SCALAR_SINGLE/runtime +Vectorization ratio [%] = 100*(FP_ARITH_INST_RETIRED_128B_PACKED_SINGLE+FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE+FP_ARITH_INST_RETIRED_512B_PACKED_SINGLE)/(FP_ARITH_INST_RETIRED_SCALAR_SINGLE+FP_ARITH_INST_RETIRED_128B_PACKED_SINGLE+FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE+FP_ARITH_INST_RETIRED_512B_PACKED_SINGLE) +- +SSE scalar and packed single precision FLOP rates. + diff --git a/collectors/likwid/groups/ICX/L2.txt b/collectors/likwid/groups/ICX/L2.txt new file mode 100644 index 0000000..efb6a1f --- /dev/null +++ b/collectors/likwid/groups/ICX/L2.txt @@ -0,0 +1,39 @@ +SHORT L2 cache bandwidth in MBytes/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +FIXC3 TOPDOWN_SLOTS +PMC0 L1D_REPLACEMENT +PMC1 L2_TRANS_L1D_WB +PMC2 ICACHE_64B_IFTAG_MISS + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L2D load bandwidth [MBytes/s] 1.0E-06*PMC0*64.0/time +L2D load data volume [GBytes] 1.0E-09*PMC0*64.0 +L2D evict bandwidth [MBytes/s] 1.0E-06*PMC1*64.0/time +L2D evict data volume [GBytes] 1.0E-09*PMC1*64.0 +L2 bandwidth [MBytes/s] 1.0E-06*(PMC0+PMC1+PMC2)*64.0/time +L2 data volume [GBytes] 1.0E-09*(PMC0+PMC1+PMC2)*64.0 + +LONG +Formulas: +L2D load bandwidth [MBytes/s] = 1.0E-06*L1D_REPLACEMENT*64.0/time +L2D load data volume [GBytes] = 1.0E-09*L1D_REPLACEMENT*64.0 +L2D evict bandwidth [MBytes/s] = 1.0E-06*L2_TRANS_L1D_WB*64.0/time +L2D evict data volume [GBytes] = 1.0E-09*L2_TRANS_L1D_WB*64.0 +L2 bandwidth [MBytes/s] = 1.0E-06*(L1D_REPLACEMENT+L2_TRANS_L1D_WB+ICACHE_64B_IFTAG_MISS)*64/time +L2 data volume [GBytes] = 1.0E-09*(L1D_REPLACEMENT+L2_TRANS_L1D_WB+ICACHE_64B_IFTAG_MISS)*64 +- +Profiling group to measure L2 cache bandwidth. The bandwidth is computed by the +number of cache line allocated in the L1 and the number of modified cache lines +evicted from the L1. The group also output total data volume transferred between +L2 and L1. Note that this bandwidth also includes data transfers due to a write +allocate load on a store miss in L1 and traffic caused by misses in the +L1 instruction cache. + diff --git a/collectors/likwid/groups/TGL/BRANCH.txt b/collectors/likwid/groups/TGL/BRANCH.txt new file mode 100644 index 0000000..b8d41b2 --- /dev/null +++ b/collectors/likwid/groups/TGL/BRANCH.txt @@ -0,0 +1,31 @@ +SHORT Branch prediction miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 BR_INST_RETIRED_ALL_BRANCHES +PMC1 BR_MISP_RETIRED_ALL_BRANCHES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Branch rate PMC0/FIXC0 +Branch misprediction rate PMC1/FIXC0 +Branch misprediction ratio PMC1/PMC0 +Instructions per branch FIXC0/PMC0 + +LONG +Formulas: +Branch rate = BR_INST_RETIRED_ALL_BRANCHES/INSTR_RETIRED_ANY +Branch misprediction rate = BR_MISP_RETIRED_ALL_BRANCHES/INSTR_RETIRED_ANY +Branch misprediction ratio = BR_MISP_RETIRED_ALL_BRANCHES/BR_INST_RETIRED_ALL_BRANCHES +Instructions per branch = INSTR_RETIRED_ANY/BR_INST_RETIRED_ALL_BRANCHES +- +The rates state how often on average a branch or a mispredicted branch occurred +per instruction retired in total. The branch misprediction ratio sets directly +into relation what ratio of all branch instruction where mispredicted. +Instructions per branch is 1/branch rate. + diff --git a/collectors/likwid/groups/TGL/DATA.txt b/collectors/likwid/groups/TGL/DATA.txt new file mode 100644 index 0000000..4e6e938 --- /dev/null +++ b/collectors/likwid/groups/TGL/DATA.txt @@ -0,0 +1,22 @@ +SHORT Load to store ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 MEM_INST_RETIRED_ALL_LOADS +PMC1 MEM_INST_RETIRED_ALL_STORES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Load to store ratio PMC0/PMC1 + +LONG +Formulas: +Load to store ratio = MEM_INST_RETIRED_ALL_LOADS/MEM_INST_RETIRED_ALL_STORES +- +This is a metric to determine your load to store ratio. + diff --git a/collectors/likwid/groups/TGL/DIVIDE.txt b/collectors/likwid/groups/TGL/DIVIDE.txt new file mode 100644 index 0000000..40b4ab6 --- /dev/null +++ b/collectors/likwid/groups/TGL/DIVIDE.txt @@ -0,0 +1,24 @@ +SHORT Divide unit information + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 ARITH_DIVIDER_COUNT +PMC1 ARITH_DIVIDER_ACTIVE + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Number of divide ops PMC0 +Avg. divide unit usage duration PMC1/PMC0 + +LONG +Formulas: +Number of divide ops = ARITH_DIVIDER_COUNT +Avg. divide unit usage duration = ARITH_DIVIDER_ACTIVE/ARITH_DIVIDER_COUNT +- +This performance group measures the average latency of divide operations diff --git a/collectors/likwid/groups/TGL/ENERGY.txt b/collectors/likwid/groups/TGL/ENERGY.txt new file mode 100644 index 0000000..fe7829f --- /dev/null +++ b/collectors/likwid/groups/TGL/ENERGY.txt @@ -0,0 +1,35 @@ +SHORT Power and Energy consumption + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +TMP0 TEMP_CORE +PWR0 PWR_PKG_ENERGY +PWR1 PWR_PP0_ENERGY +PWR3 PWR_DRAM_ENERGY + + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Temperature [C] TMP0 +Energy [J] PWR0 +Power [W] PWR0/time +Energy PP0 [J] PWR1 +Power PP0 [W] PWR1/time +Energy DRAM [J] PWR3 +Power DRAM [W] PWR3/time + +LONG +Formulas: +Power = PWR_PKG_ENERGY / time +Power PP0 = PWR_PP0_ENERGY / time +Power DRAM = PWR_DRAM_ENERGY / time +- +Broadwell implements the new RAPL interface. This interface enables to +monitor the consumed energy on the package (socket) and DRAM level. + diff --git a/collectors/likwid/groups/TGL/FLOPS_AVX.txt b/collectors/likwid/groups/TGL/FLOPS_AVX.txt new file mode 100644 index 0000000..e44a913 --- /dev/null +++ b/collectors/likwid/groups/TGL/FLOPS_AVX.txt @@ -0,0 +1,25 @@ +SHORT Packed AVX MFLOP/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE +PMC1 FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE +PMC2 FP_ARITH_INST_RETIRED_512B_PACKED_SINGLE +PMC3 FP_ARITH_INST_RETIRED_512B_PACKED_DOUBLE + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Packed SP [MFLOP/s] 1.0E-06*(PMC0*8.0+PMC2*16.0)/time +Packed DP [MFLOP/s] 1.0E-06*(PMC1*4.0+PMC3*8.0)/time + +LONG +Formulas: +Packed SP [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE*8+FP_ARITH_INST_RETIRED_512B_PACKED_SINGLE*16)/runtime +Packed DP [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE*4+FP_ARITH_INST_RETIRED_512B_PACKED_DOUBLE*8)/runtime +- +Packed 32b AVX FLOPs rates. diff --git a/collectors/likwid/groups/TGL/FLOPS_DP.txt b/collectors/likwid/groups/TGL/FLOPS_DP.txt new file mode 100644 index 0000000..177cff2 --- /dev/null +++ b/collectors/likwid/groups/TGL/FLOPS_DP.txt @@ -0,0 +1,34 @@ +SHORT Double Precision MFLOP/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 FP_ARITH_INST_RETIRED_128B_PACKED_DOUBLE +PMC1 FP_ARITH_INST_RETIRED_SCALAR_DOUBLE +PMC2 FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE +PMC3 FP_ARITH_INST_RETIRED_512B_PACKED_DOUBLE + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +DP [MFLOP/s] 1.0E-06*(PMC0*2.0+PMC1+PMC2*4.0+PMC3*8.0)/time +AVX DP [MFLOP/s] 1.0E-06*(PMC2*4.0+PMC3*8.0)/time +AVX512 DP [MFLOP/s] 1.0E-06*(PMC3*8.0)/time +Packed [MUOPS/s] 1.0E-06*(PMC0+PMC2+PMC3)/time +Scalar [MUOPS/s] 1.0E-06*PMC1/time +Vectorization ratio 100*(PMC0+PMC2+PMC3)/(PMC0+PMC1+PMC2+PMC3) + +LONG +Formulas: +DP [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_128B_PACKED_DOUBLE*2+FP_ARITH_INST_RETIRED_SCALAR_DOUBLE+FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE*4+FP_ARITH_INST_RETIRED_512B_PACKED_DOUBLE*8)/runtime +AVX DP [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE*4+FP_ARITH_INST_RETIRED_512B_PACKED_DOUBLE*8)/runtime +AVX512 DP [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_512B_PACKED_DOUBLE*8)/runtime +Packed [MUOPS/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_128B_PACKED_DOUBLE+FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE+FP_ARITH_INST_RETIRED_512B_PACKED_DOUBLE)/runtime +Scalar [MUOPS/s] = 1.0E-06*FP_ARITH_INST_RETIRED_SCALAR_DOUBLE/runtime +Vectorization ratio = 100*(FP_ARITH_INST_RETIRED_128B_PACKED_DOUBLE+FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE+FP_ARITH_INST_RETIRED_512B_PACKED_DOUBLE)/(FP_ARITH_INST_RETIRED_SCALAR_DOUBLE+FP_ARITH_INST_RETIRED_128B_PACKED_DOUBLE+FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE+FP_ARITH_INST_RETIRED_512B_PACKED_DOUBLE) +- +SSE scalar and packed double precision FLOP rates. + diff --git a/collectors/likwid/groups/TGL/FLOPS_SP.txt b/collectors/likwid/groups/TGL/FLOPS_SP.txt new file mode 100644 index 0000000..01d98c2 --- /dev/null +++ b/collectors/likwid/groups/TGL/FLOPS_SP.txt @@ -0,0 +1,34 @@ +SHORT Single Precision MFLOP/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 FP_ARITH_INST_RETIRED_128B_PACKED_SINGLE +PMC1 FP_ARITH_INST_RETIRED_SCALAR_SINGLE +PMC2 FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE +PMC3 FP_ARITH_INST_RETIRED_512B_PACKED_SINGLE + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +SP [MFLOP/s] 1.0E-06*(PMC0*4.0+PMC1+PMC2*8.0+PMC3*16.0)/time +AVX SP [MFLOP/s] 1.0E-06*(PMC2*8.0+PMC3*16.0)/time +AVX512 SP [MFLOP/s] 1.0E-06*(PMC3*16.0)/time +Packed [MUOPS/s] 1.0E-06*(PMC0+PMC2+PMC3)/time +Scalar [MUOPS/s] 1.0E-06*PMC1/time +Vectorization ratio 100*(PMC0+PMC2+PMC3)/(PMC0+PMC1+PMC2+PMC3) + +LONG +Formulas: +SP [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_128B_PACKED_SINGLE*4+FP_ARITH_INST_RETIRED_SCALAR_SINGLE+FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE*8+FP_ARITH_INST_RETIRED_512B_PACKED_SINGLE*16)/runtime +AVX SP [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE*8+FP_ARITH_INST_RETIRED_512B_PACKED_SINGLE*16)/runtime +AVX512 SP [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_512B_PACKED_SINGLE*16)/runtime +Packed [MUOPS/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_128B_PACKED_SINGLE+FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE+FP_ARITH_INST_RETIRED_512B_PACKED_SINGLE)/runtime +Scalar [MUOPS/s] = 1.0E-06*FP_ARITH_INST_RETIRED_SCALAR_SINGLE/runtime +Vectorization ratio [%] = 100*(FP_ARITH_INST_RETIRED_128B_PACKED_SINGLE+FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE+FP_ARITH_INST_RETIRED_512B_PACKED_SINGLE)/(FP_ARITH_INST_RETIRED_SCALAR_SINGLE+FP_ARITH_INST_RETIRED_128B_PACKED_SINGLE+FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE+FP_ARITH_INST_RETIRED_512B_PACKED_SINGLE) +- +SSE scalar and packed single precision FLOP rates. + diff --git a/collectors/likwid/groups/arm64fx/BRANCH.txt b/collectors/likwid/groups/arm64fx/BRANCH.txt new file mode 100644 index 0000000..dda12fb --- /dev/null +++ b/collectors/likwid/groups/arm64fx/BRANCH.txt @@ -0,0 +1,30 @@ +SHORT Branch prediction miss rate/ratio + +EVENTSET +PMC0 INST_RETIRED +PMC1 CPU_CYCLES +PMC2 BR_PRED +PMC3 BR_MIS_PRED + + +METRICS +Runtime (RDTSC) [s] time +CPI PMC1/PMC0 +Branch rate PMC2/PMC0 +Branch misprediction rate PMC3/PMC0 +Branch misprediction ratio PMC3/(PMC2+PMC3) +Instructions per branch PMC0/(PMC2+PMC3) + +LONG +Formulas: +CPI = CPU_CYCLES/INST_RETIRED +Branch rate = BR_PRED/INST_RETIRED +Branch misprediction rate = BR_MIS_PRED/INST_RETIRED +Branch misprediction ratio = BR_MIS_PRED/(BR_PRED+BR_MIS_PRED) +Instructions per branch = INSTR_RETIRED_ANY/(BR_PRED+BR_MIS_PRED) +- +The rates state how often in average a branch or a mispredicted branch occured +per instruction retired in total. The Branch misprediction ratio sets directly +into relation what ratio of all branch instruction where mispredicted. +Instructions per branch is 1/Branch rate. + diff --git a/collectors/likwid/groups/arm64fx/DATA.txt b/collectors/likwid/groups/arm64fx/DATA.txt new file mode 100644 index 0000000..40f9cb3 --- /dev/null +++ b/collectors/likwid/groups/arm64fx/DATA.txt @@ -0,0 +1,24 @@ +SHORT Load to store ratio + +EVENTSET +PMC0 INST_SPEC +PMC1 CPU_CYCLES +PMC2 LD_SPEC +PMC3 ST_SPEC + +METRICS +Runtime (RDTSC) [s] time +CPI PMC1/PMC0 +Load to store ratio PMC2/PMC3 +Load ratio PMC2/PMC0 +Store ratio PMC3/PMC0 + +LONG +Formulas: +CPI = CPU_CYCLES/INST_SPEC +Load to store ratio = LD_SPEC / ST_SPEC +Load ratio = LD_SPEC / INST_SPEC +Store ratio = ST_SPEC / INST_SPEC +- +This is a metric to determine your load to store ratio. + diff --git a/collectors/likwid/groups/arm64fx/FLOPS_DP.txt b/collectors/likwid/groups/arm64fx/FLOPS_DP.txt new file mode 100644 index 0000000..5e8a565 --- /dev/null +++ b/collectors/likwid/groups/arm64fx/FLOPS_DP.txt @@ -0,0 +1,26 @@ +SHORT Double Precision MFLOP/s + +EVENTSET +PMC0 INST_RETIRED +PMC1 CPU_CYCLES +PMC3 FP_DP_FIXED_OPS_SPEC +PMC4 FP_DP_SCALE_OPS_SPEC + +METRICS +Runtime (RDTSC) [s] time +Clock [MHz] 1.E-06*PMC1/time +CPI PMC1/PMC0 +DP (FP) [MFLOP/s] 1E-06*(PMC3)/time +DP (FP+SVE128) [MFLOP/s] 1E-06*(((PMC4*128)/128)+PMC3)/time +DP (FP+SVE256) [MFLOP/s] 1E-06*(((PMC4*256)/128)+PMC3)/time +DP (FP+SVE512) [MFLOP/s] 1E-06*(((PMC4*512)/128)+PMC3)/time + +LONG +Formulas: +DP (FP) [MFLOP/s] = 1E-06*FP_DP_FIXED_OPS_SPEC/time +DP (FP+SVE128) [MFLOP/s] = 1.0E-06*(FP_DP_FIXED_OPS_SPEC+((FP_DP_SCALE_OPS_SPEC*128)/128))/time +DP (FP+SVE256) [MFLOP/s] = 1.0E-06*(FP_DP_FIXED_OPS_SPEC+((FP_DP_SCALE_OPS_SPEC*256)/128))/time +DP (FP+SVE512) [MFLOP/s] = 1.0E-06*(FP_DP_FIXED_OPS_SPEC+((FP_DP_SCALE_OPS_SPEC*512)/128))/time +- +Double-precision FP rate for scalar and SVE vector operations with different widths. The events for +the SVE metrics assumes that all vector elements are active. diff --git a/collectors/likwid/groups/arm64fx/FLOPS_HP.txt b/collectors/likwid/groups/arm64fx/FLOPS_HP.txt new file mode 100644 index 0000000..4f449a2 --- /dev/null +++ b/collectors/likwid/groups/arm64fx/FLOPS_HP.txt @@ -0,0 +1,26 @@ +SHORT Half-Precision MFLOP/s + +EVENTSET +PMC0 INST_RETIRED +PMC1 CPU_CYCLES +PMC3 FP_HP_FIXED_OPS_SPEC +PMC4 FP_HP_SCALE_OPS_SPEC + +METRICS +Runtime (RDTSC) [s] time +Clock [MHz] 1.E-06*PMC1/time +CPI PMC1/PMC0 +HP (FP) [MFLOP/s] 1E-06*(PMC3)/time +HP (FP+SVE128) [MFLOP/s] 1E-06*(((PMC4*128)/128)+PMC3)/time +HP (FP+SVE256) [MFLOP/s] 1E-06*(((PMC4*256)/128)+PMC3)/time +HP (FP+SVE512) [MFLOP/s] 1E-06*(((PMC4*512)/128)+PMC3)/time + +LONG +Formulas: +HP (FP) [MFLOP/s] = 1E-06*FP_HP_FIXED_OPS_SPEC/time +HP (FP+SVE128) [MFLOP/s] = 1.0E-06*(FP_HP_FIXED_OPS_SPEC+((FP_HP_SCALE_OPS_SPEC*128)/128))/time +HP (FP+SVE256) [MFLOP/s] = 1.0E-06*(FP_HP_FIXED_OPS_SPEC+((FP_HP_SCALE_OPS_SPEC*256)/128))/time +HP (FP+SVE512) [MFLOP/s] = 1.0E-06*(FP_HP_FIXED_OPS_SPEC+((FP_HP_SCALE_OPS_SPEC*512)/128))/time +- +Half-precision FP rate for scalar and SVE vector operations with different widths. The events for +the SVE metrics assumes that all vector elements are active. diff --git a/collectors/likwid/groups/arm64fx/FLOPS_SP.txt b/collectors/likwid/groups/arm64fx/FLOPS_SP.txt new file mode 100644 index 0000000..d3248eb --- /dev/null +++ b/collectors/likwid/groups/arm64fx/FLOPS_SP.txt @@ -0,0 +1,26 @@ +SHORT Single Precision MFLOP/s + +EVENTSET +PMC0 INST_RETIRED +PMC1 CPU_CYCLES +PMC3 FP_SP_FIXED_OPS_SPEC +PMC4 FP_SP_SCALE_OPS_SPEC + +METRICS +Runtime (RDTSC) [s] time +Clock [MHz] 1.E-06*PMC1/time +CPI PMC1/PMC0 +SP (FP) [MFLOP/s] 1E-06*(PMC3)/time +SP (FP+SVE128) [MFLOP/s] 1E-06*(((PMC4*128)/128)+PMC3)/time +SP (FP+SVE256) [MFLOP/s] 1E-06*(((PMC4*256)/128)+PMC3)/time +SP (FP+SVE512) [MFLOP/s] 1E-06*(((PMC4*512)/128)+PMC3)/time + +LONG +Formulas: +SP (FP) [MFLOP/s] = 1E-06*FP_SP_FIXED_OPS_SPEC/time +SP (FP+SVE128) [MFLOP/s] = 1.0E-06*(FP_SP_FIXED_OPS_SPEC+((FP_SP_SCALE_OPS_SPEC*128)/128))/time +SP (FP+SVE256) [MFLOP/s] = 1.0E-06*(FP_SP_FIXED_OPS_SPEC+((FP_SP_SCALE_OPS_SPEC*256)/128))/time +SP (FP+SVE512) [MFLOP/s] = 1.0E-06*(FP_SP_FIXED_OPS_SPEC+((FP_SP_SCALE_OPS_SPEC*512)/128))/time +- +Single-precision FP rate for scalar and SVE vector operations with different widths. The events for +the SVE metrics assumes that all vector elements are active. diff --git a/collectors/likwid/groups/arm64fx/FP_PIPE.txt b/collectors/likwid/groups/arm64fx/FP_PIPE.txt new file mode 100644 index 0000000..2cde7ef --- /dev/null +++ b/collectors/likwid/groups/arm64fx/FP_PIPE.txt @@ -0,0 +1,33 @@ +SHORT Utilization of FP pipelines + +EVENTSET +PMC0 INST_RETIRED +PMC1 CPU_CYCLES +PMC2 FLA_VAL +PMC3 FLA_VAL_PRD_CNT +PMC4 FLB_VAL +PMC5 FLB_VAL_PRD_CNT + +METRICS +Runtime (RDTSC) [s] time +CPI PMC1/PMC0 +FP operation pipeline A busy rate [%] (PMC2/PMC1)*100.0 +FP pipeline A active element rate [%] (PMC3/(PMC2*16))*100.0 +FP operation pipeline B busy rate [%] (PMC4/PMC1)*100.0 +FP pipeline B active element rate [%] (PMC5/(PMC4*16))*100.0 + + +LONG +Formulas: +CPI = CPU_CYCLES/INST_SPEC +FP operation pipeline A busy rate [%] = (FLA_VAL/CPU_CYCLES)*100.0 +FP pipeline A active element rate [%] = (FLA_VAL_PRD_CNT/(FLA_VAL*16))*100.0 +FP operation pipeline B busy rate [%] = (FLB_VAL/CPU_CYCLES)*100.0 +FP pipeline B active element rate [%] = (FLB_VAL_PRD_CNT/(FLB_VAL*16))*100.0 +- +FLx_VAL: This event counts valid cycles of FLx pipeline. +FLx_VAL_PRD_CNT: This event counts the number of 1's in the predicate bits of + request in FLA pipeline, where it is corrected so that it + becomes 16 when all bits are 1. +So each predicate mask has 16 slots, so there are 16 slots per cycle in FLA and +FLB. FLA is partly used by other instructions like SVE stores. diff --git a/collectors/likwid/groups/arm64fx/ICACHE.txt b/collectors/likwid/groups/arm64fx/ICACHE.txt new file mode 100644 index 0000000..6a0bbea --- /dev/null +++ b/collectors/likwid/groups/arm64fx/ICACHE.txt @@ -0,0 +1,24 @@ +SHORT Instruction cache miss rate/ratio + +EVENTSET +PMC0 INST_RETIRED +PMC1 CPU_CYCLES +PMC2 L1I_CACHE +PMC3 L1I_CACHE_REFILL + + +METRICS +Runtime (RDTSC) [s] time +CPI PMC1/PMC0 +L1I request rate PMC2/PMC0 +L1I miss rate PMC3/PMC0 +L1I miss ratio PMC3/PMC2 + +LONG +Formulas: +CPI = CPU_CYCLES/INST_RETIRED +L1I request rate = L1I_CACHE / INST_RETIRED +L1I miss rate = L1I_CACHE_REFILL / INST_RETIRED +L1I miss ratio = L1I_CACHE_REFILL / L1I_CACHE +- +This group measures some L1 instruction cache metrics. diff --git a/collectors/likwid/groups/arm64fx/L2.txt b/collectors/likwid/groups/arm64fx/L2.txt new file mode 100644 index 0000000..be47585 --- /dev/null +++ b/collectors/likwid/groups/arm64fx/L2.txt @@ -0,0 +1,40 @@ +SHORT L2 cache bandwidth in MBytes/s + +EVENTSET +PMC0 INST_RETIRED +PMC1 CPU_CYCLES +PMC2 L1D_CACHE_REFILL +PMC3 L1D_CACHE_WB +PMC4 L1I_CACHE_REFILL + + +METRICS +Runtime (RDTSC) [s] time +CPI PMC1/PMC0 +L1D<-L2 load bandwidth [MBytes/s] 1.0E-06*(PMC2)*256.0/time +L1D<-L2 load data volume [GBytes] 1.0E-09*(PMC2)*256.0 +L1D->L2 evict bandwidth [MBytes/s] 1.0E-06*PMC3*256.0/time +L1D->L2 evict data volume [GBytes] 1.0E-09*PMC3*256.0 +L1I<-L2 load bandwidth [MBytes/s] 1.0E-06*PMC4*256.0/time +L1I<-L2 load data volume [GBytes] 1.0E-09*PMC4*256.0 +L1<->L2 bandwidth [MBytes/s] 1.0E-06*(PMC2+PMC3+PMC4)*256.0/time +L1<->L2 data volume [GBytes] 1.0E-09*(PMC2+PMC3+PMC4)*256.0 + +LONG +Formulas: +CPI = CPU_CYCLES/INST_RETIRED +L1D<-L2 load bandwidth [MBytes/s] = 1.0E-06*L1D_CACHE_REFILL*256.0/time +L1D<-L2 load data volume [GBytes] = 1.0E-09*L1D_CACHE_REFILL*256.0 +L1D->L2 evict bandwidth [MBytes/s] = 1.0E-06*L1D_CACHE_WB*256.0/time +L1D->L2 evict data volume [GBytes] = 1.0E-09*L1D_CACHE_WB*256.0 +L1I<-L2 load bandwidth [MBytes/s] = 1.0E-06*L1I_CACHE_REFILL*256.0/time +L1I<-L2 load data volume [GBytes] = 1.0E-09*L1I_CACHE_REFILL*256.0 +L1<->L2 bandwidth [MBytes/s] = 1.0E-06*(L1D_CACHE_REFILL+L1D_CACHE_WB+L1I_CACHE_REFILL)*256.0/time +L1<->L2 data volume [GBytes] = 1.0E-09*(L1D_CACHE_REFILL+L1D_CACHE_WB+L1I_CACHE_REFILL)*256.0 +- +Profiling group to measure L2 cache bandwidth. The bandwidth is computed by the +number of cacheline loaded from the L2 to the L1 data cache and the writebacks from +the L1 data cache to the L2 cache. The group also outputs total data volume transfered between +L2 and L1. Note that this bandwidth also includes data transfers due to a write +allocate load on a store miss in L1 and cachelines transfered in the L1 instruction +cache. diff --git a/collectors/likwid/groups/arm64fx/MEM.txt b/collectors/likwid/groups/arm64fx/MEM.txt new file mode 100644 index 0000000..b192b8b --- /dev/null +++ b/collectors/likwid/groups/arm64fx/MEM.txt @@ -0,0 +1,29 @@ +SHORT Main memory bandwidth in MBytes/s + +EVENTSET +PMC0 INST_RETIRED +PMC1 CPU_CYCLES +PMC2 BUS_READ_TOTAL_MEM +PMC3 BUS_WRITE_TOTAL_MEM + + +METRICS +Runtime (RDTSC) [s] time +CPI PMC1/PMC0 +Memory read bandwidth [MBytes/s] 1.0E-06*(PMC2)*256.0/time +Memory read data volume [GBytes] 1.0E-09*(PMC2)*256.0 +Memory write bandwidth [MBytes/s] 1.0E-06*(PMC3)*256.0/time +Memory write data volume [GBytes] 1.0E-09*(PMC3)*256.0 +Memory bandwidth [MBytes/s] 1.0E-06*(PMC2+PMC3)*256.0/time +Memory data volume [GBytes] 1.0E-09*(PMC2+PMC3)*256.0 + +LONG +Formulas: +Memory read bandwidth [MBytes/s] = 1.0E-06*(BUS_READ_TOTAL_MEM)*256.0/runtime +Memory read data volume [GBytes] = 1.0E-09*(BUS_READ_TOTAL_MEM)*256.0 +Memory write bandwidth [MBytes/s] = 1.0E-06*(BUS_WRITE_TOTAL_MEM)*256.0/runtime +Memory write data volume [GBytes] = 1.0E-09*(BUS_WRITE_TOTAL_MEM)*256.0 +Memory bandwidth [MBytes/s] = 1.0E-06*(BUS_READ_TOTAL_MEM+BUS_WRITE_TOTAL_MEM)*256.0/runtime +Memory data volume [GBytes] = 1.0E-09*(BUS_READ_TOTAL_MEM+BUS_WRITE_TOTAL_MEM)*256.0 +- +Profiling group to measure memory bandwidth. The cache line size is 256 Byte. diff --git a/collectors/likwid/groups/arm64fx/MEM_DP.txt b/collectors/likwid/groups/arm64fx/MEM_DP.txt new file mode 100644 index 0000000..96506ff --- /dev/null +++ b/collectors/likwid/groups/arm64fx/MEM_DP.txt @@ -0,0 +1,50 @@ +SHORT Overview of arithmetic and main memory performance + +EVENTSET +PMC0 INST_RETIRED +PMC1 CPU_CYCLES +PMC2 BUS_READ_TOTAL_MEM +PMC3 BUS_WRITE_TOTAL_MEM +PMC4 FP_DP_FIXED_OPS_SPEC +PMC5 FP_DP_SCALE_OPS_SPEC + + +METRICS +Runtime (RDTSC) [s] time +CPI PMC1/PMC0 +DP (FP) [MFLOP/s] 1E-06*(PMC4)/time +DP (FP+SVE128) [MFLOP/s] 1E-06*(((PMC5*128.0)/128.0)+PMC4)/time +DP (FP+SVE256) [MFLOP/s] 1E-06*(((PMC5*256.0)/128.0)+PMC4)/time +DP (FP+SVE512) [MFLOP/s] 1E-06*(((PMC5*512.0)/128.0)+PMC4)/time +Memory read bandwidth [MBytes/s] 1.0E-06*(PMC2)*256.0/time +Memory read data volume [GBytes] 1.0E-09*(PMC2)*256.0 +Memory write bandwidth [MBytes/s] 1.0E-06*(PMC3)*256.0/time +Memory write data volume [GBytes] 1.0E-09*(PMC3)*256.0 +Memory bandwidth [MBytes/s] 1.0E-06*(PMC2+PMC3)*256.0/time +Memory data volume [GBytes] 1.0E-09*(PMC2+PMC3)*256.0 +Operational intensity (FP) PMC4/((PMC2+PMC3)*256.0) +Operational intensity (FP+SVE128) (((PMC5*128.0)/128.0)+PMC4)/((PMC2+PMC3)*256.0) +Operational intensity (FP+SVE256) (((PMC5*256.0)/128.0)+PMC4)/((PMC2+PMC3)*256.0) +Operational intensity (FP+SVE512) (((PMC5*512.0)/128.0)+PMC4)/((PMC2+PMC3)*256.0) + + +LONG +Formulas: +DP (FP) [MFLOP/s] = 1E-06*FP_DP_FIXED_OPS_SPEC/time +DP (FP+SVE128) [MFLOP/s] = 1.0E-06*(FP_DP_FIXED_OPS_SPEC+((FP_DP_SCALE_OPS_SPEC*128)/128))/time +DP (FP+SVE256) [MFLOP/s] = 1.0E-06*(FP_DP_FIXED_OPS_SPEC+((FP_DP_SCALE_OPS_SPEC*256)/128))/time +DP (FP+SVE512) [MFLOP/s] = 1.0E-06*(FP_DP_FIXED_OPS_SPEC+((FP_DP_SCALE_OPS_SPEC*512)/128))/time +Memory read bandwidth [MBytes/s] = 1.0E-06*(BUS_READ_TOTAL_MEM)*256.0/runtime +Memory read data volume [GBytes] = 1.0E-09*(BUS_READ_TOTAL_MEM)*256.0 +Memory write bandwidth [MBytes/s] = 1.0E-06*(BUS_WRITE_TOTAL_MEM)*256.0/runtime +Memory write data volume [GBytes] = 1.0E-09*(BUS_WRITE_TOTAL_MEM)*256.0 +Memory bandwidth [MBytes/s] = 1.0E-06*(BUS_READ_TOTAL_MEM+BUS_WRITE_TOTAL_MEM)*256.0/runtime +Memory data volume [GBytes] = 1.0E-09*(BUS_READ_TOTAL_MEM+BUS_WRITE_TOTAL_MEM)*256.0 +Operational intensity (FP) = FP_DP_FIXED_OPS_SPEC/((BUS_READ_TOTAL_MEM+BUS_WRITE_TOTAL_MEM)*256.0) +Operational intensity (FP+SVE128) = (FP_DP_FIXED_OPS_SPEC+((FP_DP_SCALE_OPS_SPEC*128)/128)/((BUS_READ_TOTAL_MEM+BUS_WRITE_TOTAL_MEM)*256.0) +Operational intensity (FP+SVE256) = (FP_DP_FIXED_OPS_SPEC+((FP_DP_SCALE_OPS_SPEC*256)/128)/((BUS_READ_TOTAL_MEM+BUS_WRITE_TOTAL_MEM)*256.0) +Operational intensity (FP+SVE512) = (FP_DP_FIXED_OPS_SPEC+((FP_DP_SCALE_OPS_SPEC*512)/128)/((BUS_READ_TOTAL_MEM+BUS_WRITE_TOTAL_MEM)*256.0) +- +Profiling group to measure memory bandwidth and double-precision FP rate for scalar and SVE vector +operations with different widths. The events for the SVE metrics assumes that all vector elements +are active. The cache line size is 256 Byte. diff --git a/collectors/likwid/groups/arm64fx/MEM_HP.txt b/collectors/likwid/groups/arm64fx/MEM_HP.txt new file mode 100644 index 0000000..17d86e9 --- /dev/null +++ b/collectors/likwid/groups/arm64fx/MEM_HP.txt @@ -0,0 +1,50 @@ +SHORT Overview of arithmetic and main memory performance + +EVENTSET +PMC0 INST_RETIRED +PMC1 CPU_CYCLES +PMC2 BUS_READ_TOTAL_MEM +PMC3 BUS_WRITE_TOTAL_MEM +PMC4 FP_HP_FIXED_OPS_HPEC +PMC5 FP_HP_SCALE_OPS_HPEC + + +METRICS +Runtime (RDTSC) [s] time +CPI PMC1/PMC0 +HP (FP) [MFLOP/s] 1E-06*(PMC4)/time +HP (FP+SVE128) [MFLOP/s] 1E-06*(((PMC5*128.0)/128.0)+PMC4)/time +HP (FP+SVE256) [MFLOP/s] 1E-06*(((PMC5*256.0)/128.0)+PMC4)/time +HP (FP+SVE512) [MFLOP/s] 1E-06*(((PMC5*512.0)/128.0)+PMC4)/time +Memory read bandwidth [MBytes/s] 1.0E-06*(PMC2)*256.0/time +Memory read data volume [GBytes] 1.0E-09*(PMC2)*256.0 +Memory write bandwidth [MBytes/s] 1.0E-06*(PMC3)*256.0/time +Memory write data volume [GBytes] 1.0E-09*(PMC3)*256.0 +Memory bandwidth [MBytes/s] 1.0E-06*(PMC2+PMC3)*256.0/time +Memory data volume [GBytes] 1.0E-09*(PMC2+PMC3)*256.0 +Operational intensity (FP) PMC4/((PMC2+PMC3)*256.0) +Operational intensity (FP+SVE128) (((PMC5*128.0)/128.0)+PMC4)/((PMC2+PMC3)*256.0) +Operational intensity (FP+SVE256) (((PMC5*256.0)/128.0)+PMC4)/((PMC2+PMC3)*256.0) +Operational intensity (FP+SVE512) (((PMC5*512.0)/128.0)+PMC4)/((PMC2+PMC3)*256.0) + + +LONG +Formulas: +HP (FP) [MFLOP/s] = 1E-06*FP_HP_FIXED_OPS_HPEC/time +HP (FP+SVE128) [MFLOP/s] = 1.0E-06*(FP_HP_FIXED_OPS_HPEC+((FP_HP_SCALE_OPS_HPEC*128)/128))/time +HP (FP+SVE256) [MFLOP/s] = 1.0E-06*(FP_HP_FIXED_OPS_HPEC+((FP_HP_SCALE_OPS_HPEC*256)/128))/time +HP (FP+SVE512) [MFLOP/s] = 1.0E-06*(FP_HP_FIXED_OPS_HPEC+((FP_HP_SCALE_OPS_HPEC*512)/128))/time +Memory read bandwidth [MBytes/s] = 1.0E-06*(BUS_READ_TOTAL_MEM)*256.0/runtime +Memory read data volume [GBytes] = 1.0E-09*(BUS_READ_TOTAL_MEM)*256.0 +Memory write bandwidth [MBytes/s] = 1.0E-06*(BUS_WRITE_TOTAL_MEM)*256.0/runtime +Memory write data volume [GBytes] = 1.0E-09*(BUS_WRITE_TOTAL_MEM)*256.0 +Memory bandwidth [MBytes/s] = 1.0E-06*(BUS_READ_TOTAL_MEM+BUS_WRITE_TOTAL_MEM)*256.0/runtime +Memory data volume [GBytes] = 1.0E-09*(BUS_READ_TOTAL_MEM+BUS_WRITE_TOTAL_MEM)*256.0 +Operational intensity (FP) = FP_HP_FIXED_OPS_HPEC/((BUS_READ_TOTAL_MEM+BUS_WRITE_TOTAL_MEM)*256.0) +Operational intensity (FP+SVE128) = (FP_HP_FIXED_OPS_HPEC+((FP_HP_SCALE_OPS_HPEC*128)/128)/((BUS_READ_TOTAL_MEM+BUS_WRITE_TOTAL_MEM)*256.0) +Operational intensity (FP+SVE256) = (FP_HP_FIXED_OPS_HPEC+((FP_HP_SCALE_OPS_HPEC*256)/128)/((BUS_READ_TOTAL_MEM+BUS_WRITE_TOTAL_MEM)*256.0) +Operational intensity (FP+SVE512) = (FP_HP_FIXED_OPS_HPEC+((FP_HP_SCALE_OPS_HPEC*512)/128)/((BUS_READ_TOTAL_MEM+BUS_WRITE_TOTAL_MEM)*256.0) +- +Profiling group to measure memory bandwidth and half-precision FP rate for scalar and SVE vector +operations with different widths. The events for the SVE metrics assumes that all vector elements +are active. The cache line size is 256 Byte. diff --git a/collectors/likwid/groups/arm64fx/MEM_SP.txt b/collectors/likwid/groups/arm64fx/MEM_SP.txt new file mode 100644 index 0000000..b6220b0 --- /dev/null +++ b/collectors/likwid/groups/arm64fx/MEM_SP.txt @@ -0,0 +1,50 @@ +SHORT Overview of arithmetic and main memory performance + +EVENTSET +PMC0 INST_RETIRED +PMC1 CPU_CYCLES +PMC2 BUS_READ_TOTAL_MEM +PMC3 BUS_WRITE_TOTAL_MEM +PMC4 FP_SP_FIXED_OPS_SPEC +PMC5 FP_SP_SCALE_OPS_SPEC + + +METRICS +Runtime (RDTSC) [s] time +CPI PMC1/PMC0 +SP (FP) [MFLOP/s] 1E-06*(PMC4)/time +SP (FP+SVE128) [MFLOP/s] 1E-06*(((PMC5*128.0)/128.0)+PMC4)/time +SP (FP+SVE256) [MFLOP/s] 1E-06*(((PMC5*256.0)/128.0)+PMC4)/time +SP (FP+SVE512) [MFLOP/s] 1E-06*(((PMC5*512.0)/128.0)+PMC4)/time +Memory read bandwidth [MBytes/s] 1.0E-06*(PMC2)*256.0/time +Memory read data volume [GBytes] 1.0E-09*(PMC2)*256.0 +Memory write bandwidth [MBytes/s] 1.0E-06*(PMC3)*256.0/time +Memory write data volume [GBytes] 1.0E-09*(PMC3)*256.0 +Memory bandwidth [MBytes/s] 1.0E-06*(PMC2+PMC3)*256.0/time +Memory data volume [GBytes] 1.0E-09*(PMC2+PMC3)*256.0 +Operational intensity (FP) PMC4/((PMC2+PMC3)*256.0) +Operational intensity (FP+SVE128) (((PMC5*128.0)/128.0)+PMC4)/((PMC2+PMC3)*256.0) +Operational intensity (FP+SVE256) (((PMC5*256.0)/128.0)+PMC4)/((PMC2+PMC3)*256.0) +Operational intensity (FP+SVE512) (((PMC5*512.0)/128.0)+PMC4)/((PMC2+PMC3)*256.0) + + +LONG +Formulas: +SP (FP) [MFLOP/s] = 1E-06*FP_SP_FIXED_OPS_SPEC/time +SP (FP+SVE128) [MFLOP/s] = 1.0E-06*(FP_SP_FIXED_OPS_SPEC+((FP_SP_SCALE_OPS_SPEC*128)/128))/time +SP (FP+SVE256) [MFLOP/s] = 1.0E-06*(FP_SP_FIXED_OPS_SPEC+((FP_SP_SCALE_OPS_SPEC*256)/128))/time +SP (FP+SVE512) [MFLOP/s] = 1.0E-06*(FP_SP_FIXED_OPS_SPEC+((FP_SP_SCALE_OPS_SPEC*512)/128))/time +Memory read bandwidth [MBytes/s] = 1.0E-06*(BUS_READ_TOTAL_MEM)*256.0/runtime +Memory read data volume [GBytes] = 1.0E-09*(BUS_READ_TOTAL_MEM)*256.0 +Memory write bandwidth [MBytes/s] = 1.0E-06*(BUS_WRITE_TOTAL_MEM)*256.0/runtime +Memory write data volume [GBytes] = 1.0E-09*(BUS_WRITE_TOTAL_MEM)*256.0 +Memory bandwidth [MBytes/s] = 1.0E-06*(BUS_READ_TOTAL_MEM+BUS_WRITE_TOTAL_MEM)*256.0/runtime +Memory data volume [GBytes] = 1.0E-09*(BUS_READ_TOTAL_MEM+BUS_WRITE_TOTAL_MEM)*256.0 +Operational intensity (FP) = FP_SP_FIXED_OPS_SPEC/((BUS_READ_TOTAL_MEM+BUS_WRITE_TOTAL_MEM)*256.0) +Operational intensity (FP+SVE128) = (FP_SP_FIXED_OPS_SPEC+((FP_SP_SCALE_OPS_SPEC*128)/128)/((BUS_READ_TOTAL_MEM+BUS_WRITE_TOTAL_MEM)*256.0) +Operational intensity (FP+SVE256) = (FP_SP_FIXED_OPS_SPEC+((FP_SP_SCALE_OPS_SPEC*256)/128)/((BUS_READ_TOTAL_MEM+BUS_WRITE_TOTAL_MEM)*256.0) +Operational intensity (FP+SVE512) = (FP_SP_FIXED_OPS_SPEC+((FP_SP_SCALE_OPS_SPEC*512)/128)/((BUS_READ_TOTAL_MEM+BUS_WRITE_TOTAL_MEM)*256.0) +- +Profiling group to measure memory bandwidth and single-precision FP rate for scalar and SVE vector +operations with different widths. The events for the SVE metrics assumes that all vector elements +are active. The cache line size is 256 Byte. diff --git a/collectors/likwid/groups/arm64fx/PCI.txt b/collectors/likwid/groups/arm64fx/PCI.txt new file mode 100644 index 0000000..bca76a6 --- /dev/null +++ b/collectors/likwid/groups/arm64fx/PCI.txt @@ -0,0 +1,29 @@ +SHORT PCI bandwidth in MBytes/s + +EVENTSET +PMC0 INST_RETIRED +PMC1 CPU_CYCLES +PMC2 BUS_READ_TOTAL_PCI +PMC3 BUS_WRITE_TOTAL_PCI + + +METRICS +Runtime (RDTSC) [s] time +CPI PMC1/PMC0 +PCI read bandwidth [MBytes/s] 1.0E-06*(PMC2)*256.0/time +PCI read data volume [GBytes] 1.0E-09*(PMC2)*256.0 +PCI write bandwidth [MBytes/s] 1.0E-06*(PMC3)*256.0/time +PCI write data volume [GBytes] 1.0E-09*(PMC3)*256.0 +PCI bandwidth [MBytes/s] 1.0E-06*(PMC2+PMC3)*256.0/time +PCI data volume [GBytes] 1.0E-09*(PMC2+PMC3)*256.0 + +LONG +Formulas: +PCI read bandwidth [MBytes/s] = 1.0E-06*(BUS_READ_TOTAL_PCI)*256.0/runtime +PCI read data volume [GBytes] = 1.0E-09*(BUS_READ_TOTAL_PCI)*256.0 +PCI write bandwidth [MBytes/s] = 1.0E-06*(BUS_WRITE_TOTAL_PCI)*256.0/runtime +PCI write data volume [GBytes] = 1.0E-09*(BUS_WRITE_TOTAL_PCI)*256.0 +PCI bandwidth [MBytes/s] = 1.0E-06*(BUS_READ_TOTAL_PCI+BUS_WRITE_TOTAL_PCI)*256.0/runtime +PCI data volume [GBytes] = 1.0E-09*(BUS_READ_TOTAL_PCI+BUS_WRITE_TOTAL_PCI)*256.0 +- +Profiling group to measure PCI bandwidth. The cache line size is 256 Byte. diff --git a/collectors/likwid/groups/arm64fx/TOFU.txt b/collectors/likwid/groups/arm64fx/TOFU.txt new file mode 100644 index 0000000..2bebe3e --- /dev/null +++ b/collectors/likwid/groups/arm64fx/TOFU.txt @@ -0,0 +1,29 @@ +SHORT TOFU bandwidth in MBytes/s + +EVENTSET +PMC0 INST_RETIRED +PMC1 CPU_CYCLES +PMC2 BUS_READ_TOTAL_TOFU +PMC3 BUS_WRITE_TOTAL_TOFU + + +METRICS +Runtime (RDTSC) [s] time +CPI PMC1/PMC0 +TOFU read bandwidth [MBytes/s] 1.0E-06*(PMC2)*256.0/time +TOFU read data volume [GBytes] 1.0E-09*(PMC2)*256.0 +TOFU write bandwidth [MBytes/s] 1.0E-06*(PMC3)*256.0/time +TOFU write data volume [GBytes] 1.0E-09*(PMC3)*256.0 +TOFU bandwidth [MBytes/s] 1.0E-06*(PMC2+PMC3)*256.0/time +TOFU data volume [GBytes] 1.0E-09*(PMC2+PMC3)*256.0 + +LONG +Formulas: +TOFU read bandwidth [MBytes/s] = 1.0E-06*(BUS_READ_TOTAL_TOFU)*256.0/runtime +TOFU read data volume [GBytes] = 1.0E-09*(BUS_READ_TOTAL_TOFU)*256.0 +TOFU write bandwidth [MBytes/s] = 1.0E-06*(BUS_WRITE_TOTAL_TOFU)*256.0/runtime +TOFU write data volume [GBytes] = 1.0E-09*(BUS_WRITE_TOTAL_TOFU)*256.0 +TOFU bandwidth [MBytes/s] = 1.0E-06*(BUS_READ_TOTAL_TOFU+BUS_WRITE_TOTAL_TOFU)*256.0/runtime +TOFU data volume [GBytes] = 1.0E-09*(BUS_READ_TOTAL_TOFU+BUS_WRITE_TOTAL_TOFU)*256.0 +- +Profiling group to measure TOFU bandwidth. The cache line size is 256 Byte. diff --git a/collectors/likwid/groups/arm8/BRANCH.txt b/collectors/likwid/groups/arm8/BRANCH.txt new file mode 100644 index 0000000..8cd4f00 --- /dev/null +++ b/collectors/likwid/groups/arm8/BRANCH.txt @@ -0,0 +1,31 @@ +SHORT Branch prediction miss rate/ratio + +EVENTSET +PMC0 INST_RETIRED +PMC1 CPU_CYCLES +PMC2 BR_PRED +PMC3 BR_MIS_PRED +PMC4 INST_SPEC + + +METRICS +Runtime (RDTSC) [s] time +CPI PMC1/PMC0 +Branch rate PMC2/PMC0 +Branch misprediction rate PMC3/PMC0 +Branch misprediction ratio PMC3/(PMC2+PMC3) +Instructions per branch PMC0/(PMC2+PMC3) + +LONG +Formulas: +CPI = CPU_CYCLES/INST_RETIRED +Branch rate = BR_PRED/INST_RETIRED +Branch misprediction rate = BR_MIS_PRED/INST_RETIRED +Branch misprediction ratio = BR_MIS_PRED/(BR_PRED+BR_MIS_PRED) +Instructions per branch = INSTR_RETIRED_ANY/(BR_PRED+BR_MIS_PRED) +- +The rates state how often in average a branch or a mispredicted branch occured +per instruction retired in total. The Branch misprediction ratio sets directly +into relation what ratio of all branch instruction where mispredicted. +Instructions per branch is 1/Branch rate. + diff --git a/collectors/likwid/groups/arm8/DATA.txt b/collectors/likwid/groups/arm8/DATA.txt new file mode 100644 index 0000000..4338d90 --- /dev/null +++ b/collectors/likwid/groups/arm8/DATA.txt @@ -0,0 +1,24 @@ +SHORT Load to store ratio + +EVENTSET +PMC0 INST_RETIRED +PMC1 CPU_CYCLES +PMC2 LD_RETIRED +PMC3 ST_RETIRED + +METRICS +Runtime (RDTSC) [s] time +CPI PMC1/PMC0 +Load to store ratio PMC2/PMC3 +Load ratio PMC2/PMC0 +Store ratio PMC3/PMC0 + +LONG +Formulas: +CPI = CPU_CYCLES/INST_RETIRED +Load to store ratio = LD_RETIRED / ST_RETIRED +Load ratio = LD_RETIRED / INST_RETIRED +Store ratio = ST_RETIRED / INST_RETIRED +- +This is a metric to determine your load to store ratio. + diff --git a/collectors/likwid/groups/arm8/ICACHE.txt b/collectors/likwid/groups/arm8/ICACHE.txt new file mode 100644 index 0000000..6a0bbea --- /dev/null +++ b/collectors/likwid/groups/arm8/ICACHE.txt @@ -0,0 +1,24 @@ +SHORT Instruction cache miss rate/ratio + +EVENTSET +PMC0 INST_RETIRED +PMC1 CPU_CYCLES +PMC2 L1I_CACHE +PMC3 L1I_CACHE_REFILL + + +METRICS +Runtime (RDTSC) [s] time +CPI PMC1/PMC0 +L1I request rate PMC2/PMC0 +L1I miss rate PMC3/PMC0 +L1I miss ratio PMC3/PMC2 + +LONG +Formulas: +CPI = CPU_CYCLES/INST_RETIRED +L1I request rate = L1I_CACHE / INST_RETIRED +L1I miss rate = L1I_CACHE_REFILL / INST_RETIRED +L1I miss ratio = L1I_CACHE_REFILL / L1I_CACHE +- +This group measures some L1 instruction cache metrics. diff --git a/collectors/likwid/groups/arm8/L2.txt b/collectors/likwid/groups/arm8/L2.txt new file mode 100644 index 0000000..9f0c2e4 --- /dev/null +++ b/collectors/likwid/groups/arm8/L2.txt @@ -0,0 +1,40 @@ +SHORT L2 cache bandwidth in MBytes/s + +EVENTSET +PMC0 INST_RETIRED +PMC1 CPU_CYCLES +PMC2 L1D_CACHE_REFILL +PMC3 L1D_CACHE_WB +PMC4 L1I_CACHE_REFILL + + +METRICS +Runtime (RDTSC) [s] time +CPI PMC1/PMC0 +L2D load bandwidth [MBytes/s] 1.0E-06*PMC2*64.0/time +L2D load data volume [GBytes] 1.0E-09*PMC2*64.0 +L2D evict bandwidth [MBytes/s] 1.0E-06*PMC3*64.0/time +L2D evict data volume [GBytes] 1.0E-09*PMC3*64.0 +L2I load bandwidth [MBytes/s] 1.0E-06*PMC4*64.0/time +L2I load data volume [GBytes] 1.0E-09*PMC4*64.0 +L2 bandwidth [MBytes/s] 1.0E-06*(PMC2+PMC3+PMC4)*64.0/time +L2 data volume [GBytes] 1.0E-09*(PMC2+PMC3+PMC4)*64.0 + +LONG +Formulas: +CPI = CPU_CYCLES/INST_RETIRED +L2D load bandwidth [MBytes/s] = 1.0E-06*L1D_CACHE_REFILL*64.0/time +L2D load data volume [GBytes] = 1.0E-09*L1D_CACHE_REFILL*64.0 +L2D evict bandwidth [MBytes/s] = 1.0E-06*L1D_CACHE_WB*64.0/time +L2D evict data volume [GBytes] = 1.0E-09*L1D_CACHE_WB*64.0 +L2I load bandwidth [MBytes/s] = 1.0E-06*L1I_CACHE_REFILL*64.0/time +L2I load data volume [GBytes] = 1.0E-09*L1I_CACHE_REFILL*64.0 +L2 bandwidth [MBytes/s] = 1.0E-06*(L1D_CACHE_REFILL+L1D_CACHE_WB+L1I_CACHE_REFILL)*64.0/time +L2 data volume [GBytes] = 1.0E-09*(L1D_CACHE_REFILL+L1D_CACHE_WB+L1I_CACHE_REFILL)*64.0 +- +Profiling group to measure L2 cache bandwidth. The bandwidth is computed by the +number of cacheline loaded from the L2 to the L1 data cache and the writebacks from +the L1 data cache to the L2 cache. The group also outputs total data volume transfered between +L2 and L1. Note that this bandwidth also includes data transfers due to a write +allocate load on a store miss in L1 and cachelines transfered it the instruction +cache. diff --git a/collectors/likwid/groups/arm8/MEM.txt b/collectors/likwid/groups/arm8/MEM.txt new file mode 100644 index 0000000..d383916 --- /dev/null +++ b/collectors/likwid/groups/arm8/MEM.txt @@ -0,0 +1,30 @@ +SHORT Main memory bandwidth in MBytes/s + +EVENTSET +PMC0 INST_RETIRED +PMC1 CPU_CYCLES +PMC2 L2D_CACHE_REFILL +PMC3 L2D_CACHE_WB + + +METRICS +Runtime (RDTSC) [s] time +CPI PMC1/PMC0 +Memory read bandwidth [MBytes/s] 1.0E-06*(PMC2)*64.0/time +Memory read data volume [GBytes] 1.0E-09*(PMC2)*64.0 +Memory write bandwidth [MBytes/s] 1.0E-06*(PMC3)*64.0/time +Memory write data volume [GBytes] 1.0E-09*(PMC3)*64.0 +Memory bandwidth [MBytes/s] 1.0E-06*(PMC2+PMC3)*64.0/time +Memory data volume [GBytes] 1.0E-09*(PMC2+PMC3)*64.0 + +LONG +Formulas: +Memory read bandwidth [MBytes/s] = 1.0E-06*(L2D_CACHE_REFILL)*64.0/runtime +Memory read data volume [GBytes] = 1.0E-09*(L2D_CACHE_REFILL)*64.0 +Memory write bandwidth [MBytes/s] = 1.0E-06*(L2D_CACHE_WB)*64.0/runtime +Memory write data volume [GBytes] = 1.0E-09*(L2D_CACHE_WB)*64.0 +Memory bandwidth [MBytes/s] = 1.0E-06*(L2D_CACHE_REFILL+L2D_CACHE_WB)*64.0/runtime +Memory data volume [GBytes] = 1.0E-09*(L2D_CACHE_REFILL+L2D_CACHE_WB)*64.0 +- +Profiling group to measure memory bandwidth as initiated by the L2 cache. + diff --git a/collectors/likwid/groups/arm8_n1/BRANCH.txt b/collectors/likwid/groups/arm8_n1/BRANCH.txt new file mode 100644 index 0000000..8cd4f00 --- /dev/null +++ b/collectors/likwid/groups/arm8_n1/BRANCH.txt @@ -0,0 +1,31 @@ +SHORT Branch prediction miss rate/ratio + +EVENTSET +PMC0 INST_RETIRED +PMC1 CPU_CYCLES +PMC2 BR_PRED +PMC3 BR_MIS_PRED +PMC4 INST_SPEC + + +METRICS +Runtime (RDTSC) [s] time +CPI PMC1/PMC0 +Branch rate PMC2/PMC0 +Branch misprediction rate PMC3/PMC0 +Branch misprediction ratio PMC3/(PMC2+PMC3) +Instructions per branch PMC0/(PMC2+PMC3) + +LONG +Formulas: +CPI = CPU_CYCLES/INST_RETIRED +Branch rate = BR_PRED/INST_RETIRED +Branch misprediction rate = BR_MIS_PRED/INST_RETIRED +Branch misprediction ratio = BR_MIS_PRED/(BR_PRED+BR_MIS_PRED) +Instructions per branch = INSTR_RETIRED_ANY/(BR_PRED+BR_MIS_PRED) +- +The rates state how often in average a branch or a mispredicted branch occured +per instruction retired in total. The Branch misprediction ratio sets directly +into relation what ratio of all branch instruction where mispredicted. +Instructions per branch is 1/Branch rate. + diff --git a/collectors/likwid/groups/arm8_n1/CLOCK.txt b/collectors/likwid/groups/arm8_n1/CLOCK.txt new file mode 100644 index 0000000..ad7303a --- /dev/null +++ b/collectors/likwid/groups/arm8_n1/CLOCK.txt @@ -0,0 +1,16 @@ +SHORT Cycles and instructions + +EVENTSET +PMC0 INST_RETIRED +PMC1 CPU_CYCLES + +METRICS +Runtime (RDTSC) [s] time +CPI PMC1/PMC0 + +LONG +Formulas: +CPI = CPU_CYCLES/INST_RETIRED +- +This is a metric to determine cycles per instruction. + diff --git a/collectors/likwid/groups/arm8_n1/DATA.txt b/collectors/likwid/groups/arm8_n1/DATA.txt new file mode 100644 index 0000000..d2221a8 --- /dev/null +++ b/collectors/likwid/groups/arm8_n1/DATA.txt @@ -0,0 +1,24 @@ +SHORT Load to store ratio + +EVENTSET +PMC0 INST_RETIRED +PMC1 CPU_CYCLES +PMC2 LD_SPEC +PMC3 ST_SPEC + +METRICS +Runtime (RDTSC) [s] time +CPI PMC1/PMC0 +Load to store ratio PMC2/PMC3 +Load ratio PMC2/PMC0 +Store ratio PMC3/PMC0 + +LONG +Formulas: +CPI = CPU_CYCLES/INST_RETIRED +Load to store ratio = LD_SPEC / ST_SPEC +Load ratio = LD_SPEC / INST_SPEC +Store ratio = ST_SPEC / INST_SPEC +- +This is a metric to determine your load to store ratio. + diff --git a/collectors/likwid/groups/arm8_n1/ICACHE.txt b/collectors/likwid/groups/arm8_n1/ICACHE.txt new file mode 100644 index 0000000..6a0bbea --- /dev/null +++ b/collectors/likwid/groups/arm8_n1/ICACHE.txt @@ -0,0 +1,24 @@ +SHORT Instruction cache miss rate/ratio + +EVENTSET +PMC0 INST_RETIRED +PMC1 CPU_CYCLES +PMC2 L1I_CACHE +PMC3 L1I_CACHE_REFILL + + +METRICS +Runtime (RDTSC) [s] time +CPI PMC1/PMC0 +L1I request rate PMC2/PMC0 +L1I miss rate PMC3/PMC0 +L1I miss ratio PMC3/PMC2 + +LONG +Formulas: +CPI = CPU_CYCLES/INST_RETIRED +L1I request rate = L1I_CACHE / INST_RETIRED +L1I miss rate = L1I_CACHE_REFILL / INST_RETIRED +L1I miss ratio = L1I_CACHE_REFILL / L1I_CACHE +- +This group measures some L1 instruction cache metrics. diff --git a/collectors/likwid/groups/arm8_n1/L2.txt b/collectors/likwid/groups/arm8_n1/L2.txt new file mode 100644 index 0000000..9f0c2e4 --- /dev/null +++ b/collectors/likwid/groups/arm8_n1/L2.txt @@ -0,0 +1,40 @@ +SHORT L2 cache bandwidth in MBytes/s + +EVENTSET +PMC0 INST_RETIRED +PMC1 CPU_CYCLES +PMC2 L1D_CACHE_REFILL +PMC3 L1D_CACHE_WB +PMC4 L1I_CACHE_REFILL + + +METRICS +Runtime (RDTSC) [s] time +CPI PMC1/PMC0 +L2D load bandwidth [MBytes/s] 1.0E-06*PMC2*64.0/time +L2D load data volume [GBytes] 1.0E-09*PMC2*64.0 +L2D evict bandwidth [MBytes/s] 1.0E-06*PMC3*64.0/time +L2D evict data volume [GBytes] 1.0E-09*PMC3*64.0 +L2I load bandwidth [MBytes/s] 1.0E-06*PMC4*64.0/time +L2I load data volume [GBytes] 1.0E-09*PMC4*64.0 +L2 bandwidth [MBytes/s] 1.0E-06*(PMC2+PMC3+PMC4)*64.0/time +L2 data volume [GBytes] 1.0E-09*(PMC2+PMC3+PMC4)*64.0 + +LONG +Formulas: +CPI = CPU_CYCLES/INST_RETIRED +L2D load bandwidth [MBytes/s] = 1.0E-06*L1D_CACHE_REFILL*64.0/time +L2D load data volume [GBytes] = 1.0E-09*L1D_CACHE_REFILL*64.0 +L2D evict bandwidth [MBytes/s] = 1.0E-06*L1D_CACHE_WB*64.0/time +L2D evict data volume [GBytes] = 1.0E-09*L1D_CACHE_WB*64.0 +L2I load bandwidth [MBytes/s] = 1.0E-06*L1I_CACHE_REFILL*64.0/time +L2I load data volume [GBytes] = 1.0E-09*L1I_CACHE_REFILL*64.0 +L2 bandwidth [MBytes/s] = 1.0E-06*(L1D_CACHE_REFILL+L1D_CACHE_WB+L1I_CACHE_REFILL)*64.0/time +L2 data volume [GBytes] = 1.0E-09*(L1D_CACHE_REFILL+L1D_CACHE_WB+L1I_CACHE_REFILL)*64.0 +- +Profiling group to measure L2 cache bandwidth. The bandwidth is computed by the +number of cacheline loaded from the L2 to the L1 data cache and the writebacks from +the L1 data cache to the L2 cache. The group also outputs total data volume transfered between +L2 and L1. Note that this bandwidth also includes data transfers due to a write +allocate load on a store miss in L1 and cachelines transfered it the instruction +cache. diff --git a/collectors/likwid/groups/arm8_n1/L3.txt b/collectors/likwid/groups/arm8_n1/L3.txt new file mode 100644 index 0000000..3c8a73e --- /dev/null +++ b/collectors/likwid/groups/arm8_n1/L3.txt @@ -0,0 +1,30 @@ +SHORT L3 cache bandwidth in MBytes/s + +EVENTSET +PMC0 INST_RETIRED +PMC1 CPU_CYCLES +PMC2 L2D_CACHE_REFILL +PMC3 L2D_CACHE_WB + + +METRICS +Runtime (RDTSC) [s] time +CPI PMC1/PMC0 +L3 read bandwidth [MBytes/s] 1.0E-06*(PMC2)*64.0/time +L3 read data volume [GBytes] 1.0E-09*(PMC2)*64.0 +L3 write bandwidth [MBytes/s] 1.0E-06*(PMC3)*64.0/time +L3 write data volume [GBytes] 1.0E-09*(PMC3)*64.0 +L3 bandwidth [MBytes/s] 1.0E-06*(PMC2+PMC3)*64.0/time +L3 data volume [GBytes] 1.0E-09*(PMC2+PMC3)*64.0 + +LONG +Formulas: +L3 read bandwidth [MBytes/s] = 1.0E-06*(L2D_CACHE_REFILL)*64.0/runtime +L3 read data volume [GBytes] = 1.0E-09*(L2D_CACHE_REFILL)*64.0 +L3 write bandwidth [MBytes/s] = 1.0E-06*(L2D_CACHE_WB)*64.0/runtime +L3 write data volume [GBytes] = 1.0E-09*(L2D_CACHE_WB)*64.0 +L3 bandwidth [MBytes/s] = 1.0E-06*(L2D_CACHE_REFILL+L2D_CACHE_WB)*64.0/runtime +L3 data volume [GBytes] = 1.0E-09*(L2D_CACHE_REFILL+L2D_CACHE_WB)*64.0 +- +Profiling group to measure traffic between L2 and L3 cache. + diff --git a/collectors/likwid/groups/arm8_n1/MEM.txt b/collectors/likwid/groups/arm8_n1/MEM.txt new file mode 100644 index 0000000..8c334bb --- /dev/null +++ b/collectors/likwid/groups/arm8_n1/MEM.txt @@ -0,0 +1,29 @@ +SHORT Main memory bandwidth in MBytes/s + +EVENTSET +PMC0 INST_RETIRED +PMC1 CPU_CYCLES +PMC2 MEM_ACCESS_RD +PMC3 MEM_ACCESS_WR + +METRICS +Runtime (RDTSC) [s] time +CPI PMC1/PMC0 +Memory read bandwidth [MBytes/s] 1.0E-06*(PMC2)*64.0/time +Memory read data volume [GBytes] 1.0E-09*(PMC2)*64.0 +Memory write bandwidth [MBytes/s] 1.0E-06*(PMC3)*64.0/time +Memory write data volume [GBytes] 1.0E-09*(PMC3)*64.0 +Memory bandwidth [MBytes/s] 1.0E-06*(PMC2+PMC3)*64.0/time +Memory data volume [GBytes] 1.0E-09*(PMC2+PMC3)*64.0 + +LONG +Formulas: +Memory read bandwidth [MBytes/s] = 1.0E-06*(MEM_ACCESS_RD)*64.0/runtime +Memory read data volume [GBytes] = 1.0E-09*(MEM_ACCESS_RD)*64.0 +Memory write bandwidth [MBytes/s] = 1.0E-06*(MEM_ACCESS_WR)*64.0/runtime +Memory write data volume [GBytes] = 1.0E-09*(MEM_ACCESS_WR)*64.0 +Memory bandwidth [MBytes/s] = 1.0E-06*(MEM_ACCESS_RD+MEM_ACCESS_WR)*64.0/runtime +Memory data volume [GBytes] = 1.0E-09*(MEM_ACCESS_RD+MEM_ACCESS_WR)*64.0 +- +Profiling group to measure memory bandwidth + diff --git a/collectors/likwid/groups/arm8_n1/TLB.txt b/collectors/likwid/groups/arm8_n1/TLB.txt new file mode 100644 index 0000000..4e588b1 --- /dev/null +++ b/collectors/likwid/groups/arm8_n1/TLB.txt @@ -0,0 +1,30 @@ +SHORT L1/L2 TLB information + +EVENTSET +PMC0 L1D_TLB +PMC1 L1I_TLB +PMC2 L2D_TLB +PMC3 L1D_TLB_REFILL +PMC4 L1I_TLB_REFILL +PMC5 L2D_TLB_REFILL + +METRICS +Runtime (RDTSC) [s] time +L1 DTLB accesses PMC0 +L1 ITLB accesses PMC1 +L2 DTLB accesses PMC2 +L1 DTLB refills PMC3 +L1 ITLB refills PMC4 +L2 DTLB refills PMC5 +L1 DTLB refill ratio PMC3/PMC0 +L1 ITLB refill ratio PMC4/PMC1 +L1 DTLB refill ratio PMC5/PMC2 + +LONG +Formulas: +L1 DTLB refill ratio = L1D_TLB_REFILL / L1D_TLB +L1 ITLB refill ratio = L1I_TLB_REFILL / L1I_TLB +L2 DTLB refill ratio = L2D_TLB_REFILL / L2D_TLB +- +This group gives information about the TLB usage for all TLBs: +L1 data, L1 instruction and L2 data. diff --git a/collectors/likwid/groups/arm8_tx2/BRANCH.txt b/collectors/likwid/groups/arm8_tx2/BRANCH.txt new file mode 100644 index 0000000..db0fa40 --- /dev/null +++ b/collectors/likwid/groups/arm8_tx2/BRANCH.txt @@ -0,0 +1,32 @@ +SHORT Branch prediction miss rate/ratio + +EVENTSET +PMC0 INST_RETIRED +PMC1 CPU_CYCLES +PMC2 BR_PRED +PMC3 BR_MIS_PRED +PMC4 INST_SPEC + + +METRICS +Runtime (RDTSC) [s] time +Clock [MHz] 1.E-06*PMC1/time +CPI PMC1/PMC0 +Branch rate PMC2/PMC0 +Branch misprediction rate PMC3/PMC0 +Branch misprediction ratio PMC3/(PMC2+PMC3) +Instructions per branch PMC0/(PMC2+PMC3) + +LONG +Formulas: +CPI = CPU_CYCLES/INST_RETIRED +Branch rate = BR_PRED/INST_RETIRED +Branch misprediction rate = BR_MIS_PRED/INST_RETIRED +Branch misprediction ratio = BR_MIS_PRED/(BR_PRED+BR_MIS_PRED) +Instructions per branch = INSTR_RETIRED_ANY/(BR_PRED+BR_MIS_PRED) +- +The rates state how often in average a branch or a mispredicted branch occured +per instruction retired in total. The Branch misprediction ratio sets directly +into relation what ratio of all branch instruction where mispredicted. +Instructions per branch is 1/Branch rate. + diff --git a/collectors/likwid/groups/arm8_tx2/DATA.txt b/collectors/likwid/groups/arm8_tx2/DATA.txt new file mode 100644 index 0000000..09681c2 --- /dev/null +++ b/collectors/likwid/groups/arm8_tx2/DATA.txt @@ -0,0 +1,25 @@ +SHORT Load to store ratio + +EVENTSET +PMC0 INST_RETIRED +PMC1 CPU_CYCLES +PMC2 LD_RETIRED +PMC3 ST_RETIRED + +METRICS +Runtime (RDTSC) [s] time +Clock [MHz] 1.E-06*PMC1/time +CPI PMC1/PMC0 +Load to store ratio PMC2/PMC3 +Load ratio PMC2/PMC0 +Store ratio PMC3/PMC0 + +LONG +Formulas: +CPI = CPU_CYCLES/INST_RETIRED +Load to store ratio = LD_RETIRED / ST_RETIRED +Load ratio = LD_RETIRED / INST_RETIRED +Store ratio = ST_RETIRED / INST_RETIRED +- +This is a metric to determine your load to store ratio. + diff --git a/collectors/likwid/groups/arm8_tx2/FLOPS_DP.txt b/collectors/likwid/groups/arm8_tx2/FLOPS_DP.txt new file mode 100644 index 0000000..5b477de --- /dev/null +++ b/collectors/likwid/groups/arm8_tx2/FLOPS_DP.txt @@ -0,0 +1,28 @@ +SHORT Double Precision MFLOP/s + +EVENTSET +PMC0 INST_RETIRED +PMC1 CPU_CYCLES +PMC2 VFP_SPEC +PMC3 ASE_SPEC + +METRICS +Runtime (RDTSC) [s] time +Clock [MHz] 1.E-06*PMC1/time +CPI PMC1/PMC0 +DP [MFLOP/s] 1.0E-06*(PMC3*2.0+PMC2)/time +NEON DP [MFLOP/s] 1.0E-06*(PMC3*2.0)/time +Packed [MUOPS/s] 1.0E-06*(PMC3)/time +Scalar [MUOPS/s] 1.0E-06*PMC2/time +Vectorization ratio 100*(PMC3)/(PMC2+PMC3) + +LONG +Formulas: +DP [MFLOP/s] = 1.0E-06*(ASE_SPEC*2+VFP_SPEC)/runtime +NEON DP [MFLOP/s] = 1.0E-06*(ASE_SPEC*4)/runtime +Packed [MUOPS/s] = 1.0E-06*(ASE_SPEC)/runtime +Scalar [MUOPS/s] = 1.0E-06*VFP_SPEC/runtime +Vectorization ratio = 100*(ASE_SPEC)/(ASE_SPEC+VFP_SPEC) +- +NEON scalar and packed double precision FLOP rates. + diff --git a/collectors/likwid/groups/arm8_tx2/FLOPS_SP.txt b/collectors/likwid/groups/arm8_tx2/FLOPS_SP.txt new file mode 100644 index 0000000..9857308 --- /dev/null +++ b/collectors/likwid/groups/arm8_tx2/FLOPS_SP.txt @@ -0,0 +1,28 @@ +SHORT Single Precision MFLOP/s + +EVENTSET +PMC0 INST_RETIRED +PMC1 CPU_CYCLES +PMC2 VFP_SPEC +PMC3 ASE_SPEC + +METRICS +Runtime (RDTSC) [s] time +Clock [MHz] 1.E-06*PMC1/time +CPI PMC1/PMC0 +SP [MFLOP/s] 1.0E-06*(PMC3*2.0+PMC2)/time +NEON SP [MFLOP/s] 1.0E-06*(PMC3*2.0)/time +Packed [MUOPS/s] 1.0E-06*(PMC3)/time +Scalar [MUOPS/s] 1.0E-06*PMC2/time +Vectorization ratio 100*(PMC3)/(PMC2+PMC3) + +LONG +Formulas: +SP [MFLOP/s] = 1.0E-06*(ASE_SPEC*2+VFP_SPEC)/runtime +NEON SP [MFLOP/s] = 1.0E-06*(ASE_SPEC*4)/runtime +Packed [MUOPS/s] = 1.0E-06*(ASE_SPEC)/runtime +Scalar [MUOPS/s] = 1.0E-06*VFP_SPEC/runtime +Vectorization ratio = 100*(ASE_SPEC)/(ASE_SPEC+VFP_SPEC) +- +NEON scalar and packed single precision FLOP rates. + diff --git a/collectors/likwid/groups/arm8_tx2/ICACHE.txt b/collectors/likwid/groups/arm8_tx2/ICACHE.txt new file mode 100644 index 0000000..fbaf3be --- /dev/null +++ b/collectors/likwid/groups/arm8_tx2/ICACHE.txt @@ -0,0 +1,23 @@ +SHORT Instruction cache miss rate/ratio + +EVENTSET +PMC0 INST_RETIRED +PMC1 CPU_CYCLES +PMC2 L1I_CACHE +PMC3 L1I_CACHE_REFILL + +METRICS +Runtime (RDTSC) [s] time +Clock [MHz] 1.E-06*PMC1/time +CPI PMC1/PMC0 +L1I request rate PMC2/PMC0 +L1I miss rate PMC3/PMC0 +L1I miss ratio PMC3/PMC2 + +LONG +Formulas: +L1I request rate = L1I_CACHE / INST_RETIRED +L1I miss rate = L1I_CACHE_REFILL / INST_RETIRED +L1I miss ratio = L1I_CACHE_REFILL / L1I_CACHE +- +This group measures some L1 instruction cache metrics. diff --git a/collectors/likwid/groups/arm8_tx2/L2.txt b/collectors/likwid/groups/arm8_tx2/L2.txt new file mode 100644 index 0000000..53bec4c --- /dev/null +++ b/collectors/likwid/groups/arm8_tx2/L2.txt @@ -0,0 +1,41 @@ +SHORT L2 cache bandwidth in MBytes/s + +EVENTSET +PMC0 INST_RETIRED +PMC1 CPU_CYCLES +PMC2 L1D_CACHE_REFILL +PMC3 L1D_CACHE_WB +PMC4 L1I_CACHE_REFILL + + +METRICS +Runtime (RDTSC) [s] time +Clock [MHz] 1.E-06*PMC1/time +CPI PMC1/PMC0 +L2D load bandwidth [MBytes/s] 1.0E-06*PMC2*64.0/time +L2D load data volume [GBytes] 1.0E-09*PMC2*64.0 +L2D evict bandwidth [MBytes/s] 1.0E-06*PMC3*64.0/time +L2D evict data volume [GBytes] 1.0E-09*PMC3*64.0 +L2I load bandwidth [MBytes/s] 1.0E-06*PMC4*64.0/time +L2I load data volume [GBytes] 1.0E-09*PMC4*64.0 +L2 bandwidth [MBytes/s] 1.0E-06*(PMC2+PMC3+PMC4)*64.0/time +L2 data volume [GBytes] 1.0E-09*(PMC2+PMC3+PMC4)*64.0 + +LONG +Formulas: +CPI = CPU_CYCLES/INST_RETIRED +L2D load bandwidth [MBytes/s] = 1.0E-06*L1D_CACHE_REFILL*64.0/time +L2D load data volume [GBytes] = 1.0E-09*L1D_CACHE_REFILL*64.0 +L2D evict bandwidth [MBytes/s] = 1.0E-06*L1D_CACHE_WB*64.0/time +L2D evict data volume [GBytes] = 1.0E-09*L1D_CACHE_WB*64.0 +L2I load bandwidth [MBytes/s] = 1.0E-06*L1I_CACHE_REFILL*64.0/time +L2I load data volume [GBytes] = 1.0E-09*L1I_CACHE_REFILL*64.0 +L2 bandwidth [MBytes/s] = 1.0E-06*(L1D_CACHE_REFILL+L1D_CACHE_WB+L1I_CACHE_REFILL)*64.0/time +L2 data volume [GBytes] = 1.0E-09*(L1D_CACHE_REFILL+L1D_CACHE_WB+L1I_CACHE_REFILL)*64.0 +- +Profiling group to measure L2 cache bandwidth. The bandwidth is computed by the +number of cacheline loaded from the L2 to the L1 data cache and the writebacks from +the L1 data cache to the L2 cache. The group also outputs total data volume transfered between +L2 and L1. Note that this bandwidth also includes data transfers due to a write +allocate load on a store miss in L1 and cachelines transfered it the instruction +cache. diff --git a/collectors/likwid/groups/arm8_tx2/L2CACHE.txt b/collectors/likwid/groups/arm8_tx2/L2CACHE.txt new file mode 100644 index 0000000..4696e28 --- /dev/null +++ b/collectors/likwid/groups/arm8_tx2/L2CACHE.txt @@ -0,0 +1,32 @@ +SHORT L2 cache miss rate/ratio + +EVENTSET +PMC0 INST_RETIRED +PMC1 CPU_CYCLES +PMC2 L2D_CACHE +PMC3 L2D_CACHE_REFILL + +METRICS +Runtime (RDTSC) [s] time +Clock [MHz] 1.E-06*PMC1/time +CPI PMC1/PMC0 +L2 request rate PMC2/PMC0 +L2 miss rate PMC3/PMC0 +L2 miss ratio PMC3/PMC2 + +LONG +Formulas: +L2 request rate = L2D_CACHE/INST_RETIRED +L2 miss rate = L2D_CACHE_REFILL/INST_RETIRED +L2 miss ratio = L2D_CACHE_REFILL/L2D_CACHE +- +This group measures the locality of your data accesses with regard to the +L2 cache. L2 request rate tells you how data intensive your code is +or how many data accesses you have on average per instruction. +The L2 miss rate gives a measure how often it was necessary to get +cache lines from memory. And finally L2 miss ratio tells you how many of your +memory references required a cache line to be loaded from a higher level. +While the data cache miss rate might be given by your algorithm you should +try to get data cache miss ratio as low as possible by increasing your cache reuse. + + diff --git a/collectors/likwid/groups/arm8_tx2/L3.txt b/collectors/likwid/groups/arm8_tx2/L3.txt new file mode 100644 index 0000000..4c99a05 --- /dev/null +++ b/collectors/likwid/groups/arm8_tx2/L3.txt @@ -0,0 +1,38 @@ +SHORT L3 cache bandwidth in MBytes/s + +EVENTSET +PMC0 INST_RETIRED +PMC1 CPU_CYCLES +PMC2 L2D_CACHE_REFILL +PMC3 L2D_CACHE_WB +PMC4 L2D_CACHE_ALLOCATE + + +METRICS +Runtime (RDTSC) [s] time +Clock [MHz] 1.E-06*PMC1/time +CPI PMC1/PMC0 +L3 load bandwidth [MBytes/s] 1.0E-06*(PMC2-PMC4)*64.0/time +L3 load data volume [GBytes] 1.0E-09*(PMC2-PMC4)*64.0 +L3 evict bandwidth [MBytes/s] 1.0E-06*PMC3*64.0/time +L3 evict data volume [GBytes] 1.0E-09*PMC3*64.0 +L3 bandwidth [MBytes/s] 1.0E-06*(PMC2+PMC3-PMC4)*64.0/time +L3 data volume [GBytes] 1.0E-09*(PMC2+PMC3-PMC4)*64.0 + +LONG +Formulas: +CPI = CPU_CYCLES/INST_RETIRED +L3 load bandwidth [MBytes/s] = 1.0E-06*(L2D_CACHE_REFILL-L2D_CACHE_ALLOCATE)*64.0/time +L3 load data volume [GBytes] = 1.0E-09*(L2D_CACHE_REFILL-L2D_CACHE_ALLOCATE)*64.0 +L3 evict bandwidth [MBytes/s] = 1.0E-06*L2D_CACHE_WB*64.0/time +L3 evict data volume [GBytes] = 1.0E-09*L2D_CACHE_WB*64.0 +L3 bandwidth [MBytes/s] = 1.0E-06*(L2D_CACHE_REFILL+L2D_CACHE_WB-L2D_CACHE_ALLOCATE))*64.0/time +L3 data volume [GBytes] = 1.0E-09*(L2D_CACHE_REFILL+L2D_CACHE_WB-L2D_CACHE_ALLOCATE))*64.0 +- +Profiling group to measure L2 <-> L3 cache bandwidth. The bandwidth is computed by the +number of cache lines loaded from the L3 to the L2 data cache and the writebacks from +the L2 data cache to the L3 cache. The group also outputs total data volume transfered between +L3 and L2. For streaming-stores, the cache lines are allocated in L2, consequently there +is no traffic between L3 and L2 in this case. But the L2D_CACHE_REFILL event counts these +allocated cache lines, that's why the value of L2D_CACHE_REFILL is reduced +by L2D_CACHE_ALLOCATE. diff --git a/collectors/likwid/groups/arm8_tx2/MEM.txt b/collectors/likwid/groups/arm8_tx2/MEM.txt new file mode 100644 index 0000000..06bc697 --- /dev/null +++ b/collectors/likwid/groups/arm8_tx2/MEM.txt @@ -0,0 +1,32 @@ +SHORT Main memory bandwidth in MBytes/s + +EVENTSET +PMC0 INST_RETIRED +PMC1 CPU_CYCLES +MBOX0C0 MEMORY_READS +MBOX0C1 MEMORY_WRITES +MBOX1C0 MEMORY_READS +MBOX1C1 MEMORY_WRITES + +METRICS +Runtime (RDTSC) [s] time +Clock [MHz] 1.E-06*PMC1/time +CPI PMC1/PMC0 +Memory read bandwidth [MBytes/s] 1.0E-06*(MBOX0C0+MBOX1C0)*64.0/time +Memory read data volume [GBytes] 1.0E-09*(MBOX0C0+MBOX1C0)*64.0 +Memory write bandwidth [MBytes/s] 1.0E-06*(MBOX0C1+MBOX1C1)*64.0/time +Memory write data volume [GBytes] 1.0E-09*(MBOX0C1+MBOX1C1)*64.0 +Memory bandwidth [MBytes/s] 1.0E-06*(MBOX0C0+MBOX1C0+MBOX0C1+MBOX1C1)*64.0/time +Memory data volume [GBytes] 1.0E-09*(MBOX0C0+MBOX1C0+MBOX0C1+MBOX1C1)*64.0 + +LONG +Formulas: +Memory read bandwidth [MBytes/s] = 1.0E-06*(SUM(MEMORY_READS))*64.0/runtime +Memory read data volume [GBytes] = 1.0E-09*(SUM(MEMORY_READS))*64.0 +Memory write bandwidth [MBytes/s] = 1.0E-06*(SUM(MEMORY_WRITES))*64.0/runtime +Memory write data volume [GBytes] = 1.0E-09*(SUM(MEMORY_WRITES))*64.0 +Memory bandwidth [MBytes/s] = 1.0E-06*(SUM(MEMORY_READS)+SUM(MEMORY_WRITES))*64.0/runtime +Memory data volume [GBytes] = 1.0E-09*(SUM(MEMORY_READS)+SUM(MEMORY_WRITES))*64.0 +- +Profiling group to measure memory bandwidth. It uses the performance monitoring +hardware of the memory controllers. diff --git a/collectors/likwid/groups/arm8_tx2/SPEC.txt b/collectors/likwid/groups/arm8_tx2/SPEC.txt new file mode 100644 index 0000000..7561d3a --- /dev/null +++ b/collectors/likwid/groups/arm8_tx2/SPEC.txt @@ -0,0 +1,44 @@ +SHORT Information about speculative execution + +EVENTSET +PMC0 INST_SPEC +PMC1 LD_SPEC +PMC2 ST_SPEC +PMC3 DP_SPEC +PMC4 VFP_SPEC +PMC5 ASE_SPEC + + +METRICS +Runtime (RDTSC) [s] time +Operations spec. executed PMC0 +Load ops spec. executed PMC1 +Store ops spec. executed PMC2 +Integer data ops spec. executed PMC3 +Scalar FP ops spec. executed PMC4 +Vector FP ops spec. executed PMC5 +Other ops spec. executed (PMC0-PMC1-PMC2-PMC3-PMC4-PMC5) +Load ops spec. ratio PMC1/PMC0 +Store ops spec. ratio PMC2/PMC0 +Integer data ops spec. ratio PMC3/PMC0 +Scalar FP ops spec. ratio PMC4/PMC0 +Vector FP ops spec. ratio PMC5/PMC0 +Other ops spec. ratio (PMC0-PMC1-PMC2-PMC3-PMC4-PMC5)/PMC0 + + + + +LONG +Formulas: +Load ops spec. ratio = LD_SPEC / INST_SPEC +Store ops spec. ratio = ST_SPEC / INST_SPEC +Integer data ops spec. ratio = DP_SPEC / INST_SPEC +Scalar FP ops spec. ratio = VFP_SPEC / INST_SPEC +Vector FP ops spec. ratio = ASE_SPEC / INST_SPEC +Other ops spec. ratio = (INST_SPEC-LD_SPEC-ST_SPEC-DP_SPEC-VFP_SPEC-ASE_SPEC) / INST_SPEC +- +This group gives information about the speculative execution of micro-ops. +It is currently unclear why Other ops spec. executed and ratio is negative +in some cases. Although the documentation contains an OP_RETIRED, there is no +equivalent OP_SPEC which could be a better reference in this group instead of +INST_SPEC. diff --git a/collectors/likwid/groups/arm8_tx2/TLB_DATA.txt b/collectors/likwid/groups/arm8_tx2/TLB_DATA.txt new file mode 100644 index 0000000..054b0ec --- /dev/null +++ b/collectors/likwid/groups/arm8_tx2/TLB_DATA.txt @@ -0,0 +1,27 @@ +SHORT L1 data TLB miss rate/ratio + +EVENTSET +PMC0 INST_RETIRED +PMC1 CPU_CYCLES +PMC2 L1D_TLB_REFILL_RD +PMC3 L1D_TLB_REFILL_WR + +METRICS +Runtime (RDTSC) [s] time +Clock [MHz] 1.E-06*PMC1/time +CPI PMC1/PMC0 +L1 DTLB load misses PMC2 +L1 DTLB load miss rate PMC2/PMC0 +L1 DTLB store misses PMC3 +L1 DTLB store miss rate PMC3/PMC0 + +LONG +Formulas: +L1 DTLB load misses = L1D_TLB_REFILL_RD +L1 DTLB load miss rate = L1D_TLB_REFILL_RD / INST_RETIRED +L1 DTLB store misses = L1D_TLB_REFILL_WR +L1 DTLB store miss rate = L1D_TLB_REFILL_WR / INST_RETIRED +- +The DTLB load and store miss rates gives a measure how often a TLB miss occurred +per instruction. + diff --git a/collectors/likwid/groups/arm8_tx2/TLB_INSTR.txt b/collectors/likwid/groups/arm8_tx2/TLB_INSTR.txt new file mode 100644 index 0000000..c1111c8 --- /dev/null +++ b/collectors/likwid/groups/arm8_tx2/TLB_INSTR.txt @@ -0,0 +1,23 @@ +SHORT L1 Instruction TLB miss rate/ratio + +EVENTSET +PMC0 INST_RETIRED +PMC1 CPU_CYCLES +PMC2 L1I_TLB_REFILL + +METRICS +Runtime (RDTSC) [s] time +Clock [MHz] 1.E-06*PMC1/time +CPI PMC1/PMC0 +L1 ITLB misses PMC2 +L1 ITLB miss rate PMC2/PMC0 + + +LONG +Formulas: +L1 ITLB misses = L1I_TLB_REFILL +L1 ITLB miss rate = L1I_TLB_REFILL / INST_RETIRED +- +The ITLB miss rates gives a measure how often a TLB miss occurred +per instruction. + diff --git a/collectors/likwid/groups/atom/BRANCH.txt b/collectors/likwid/groups/atom/BRANCH.txt new file mode 100644 index 0000000..7b2bb20 --- /dev/null +++ b/collectors/likwid/groups/atom/BRANCH.txt @@ -0,0 +1,29 @@ +SHORT Branch prediction miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +PMC0 BR_INST_RETIRED_ANY +PMC1 BR_INST_RETIRED_MISPRED + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +CPI FIXC1/FIXC0 +Branch rate PMC0/FIXC0 +Branch misprediction rate PMC1/FIXC0 +Branch misprediction ratio PMC1/PMC0 +Instructions per branch FIXC0/PMC0 + +LONG +Formulas: +Branch rate = BR_INST_RETIRED_ANY/INSTR_RETIRED_ANY +Branch misprediction rate = BR_INST_RETIRED_MISPRED/INSTR_RETIRED_ANY +Branch misprediction ratio = BR_INST_RETIRED_MISPRED/BR_INST_RETIRED_ANY +Instructions per branch = INSTR_RETIRED_ANY/BR_INST_RETIRED_ANY +- +The rates state how often on average a branch or a mispredicted branch occurred +per instruction retired in total. The branch misprediction ratio sets directly +into relation what ratio of all branch instruction where mispredicted. +Instructions per branch is 1/branch rate. + diff --git a/collectors/likwid/groups/atom/DATA.txt b/collectors/likwid/groups/atom/DATA.txt new file mode 100644 index 0000000..b2d007f --- /dev/null +++ b/collectors/likwid/groups/atom/DATA.txt @@ -0,0 +1,20 @@ +SHORT Load to store ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +PMC0 L1D_CACHE_LD +PMC1 L1D_CACHE_ST + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +CPI FIXC1/FIXC0 +Load to store ratio PMC0/PMC1 + +LONG +Formulas: +Load to store ratio = L1D_CACHE_LD/L1D_CACHE_ST +- +This is a simple metric to determine your load to store ratio. + diff --git a/collectors/likwid/groups/atom/FLOPS_DP.txt b/collectors/likwid/groups/atom/FLOPS_DP.txt new file mode 100644 index 0000000..53b2d02 --- /dev/null +++ b/collectors/likwid/groups/atom/FLOPS_DP.txt @@ -0,0 +1,25 @@ +SHORT Double Precision MFLOP/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +PMC0 SIMD_COMP_INST_RETIRED_PACKED_DOUBLE +PMC1 SIMD_COMP_INST_RETIRED_SCALAR_DOUBLE + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +CPI FIXC1/FIXC0 +DP [MFLOP/s] 1.0E-06*(PMC0*2.0+PMC1)/time +Packed [MUOPS/s] 1.0E-06*PMC0/time +Scalar [MUOPS/s] 1.0E-06*PMC1/time + + +LONG +Formulas: +DP [MFLOP/s] = 1.0E-06*(SIMD_COMP_INST_RETIRED_PACKED_DOUBLE*2.0+SIMD_COMP_INST_RETIRED_SCALAR_DOUBLE)/runtime +Packed [MUOPS/s] = 1.0E-06*SIMD_COMP_INST_RETIRED_PACKED_DOUBLE/runtime +Scalar [MUOPS/s] = 1.0E-06*SIMD_COMP_INST_RETIRED_SCALAR_DOUBLE/runtime +-- +Double Precision [MFLOP/s] Double Precision MFLOP/s + diff --git a/collectors/likwid/groups/atom/FLOPS_SP.txt b/collectors/likwid/groups/atom/FLOPS_SP.txt new file mode 100644 index 0000000..0046d5b --- /dev/null +++ b/collectors/likwid/groups/atom/FLOPS_SP.txt @@ -0,0 +1,24 @@ +SHORT Single Precision MFLOP/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +PMC0 SIMD_COMP_INST_RETIRED_PACKED_SINGLE +PMC1 SIMD_COMP_INST_RETIRED_SCALAR_SINGLE + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +CPI FIXC1/FIXC0 +SP [MFLOP/s] (SP assumed) 1.0E-06*(PMC0*4.0+PMC1)/time +Packed [MUOPS/s] 1.0E-06*(PMC0)/time +Scalar [MUOPS/s] 1.0E-06*PMC1/time + +LONG +Formulas: +SP [MFLOP/s] = 1.0E-06*(SIMD_COMP_INST_RETIRED_PACKED_DOUBLE*4.0+SIMD_COMP_INST_RETIRED_SCALAR_DOUBLE)/runtime +Packed [MUOPS/s] = 1.0E-06*SIMD_COMP_INST_RETIRED_PACKED_SINGLE/runtime +Scalar [MUOPS/s] = 1.0E-06*SIMD_COMP_INST_RETIRED_SCALAR_SINGLE/runtime +-- +Single Precision MFLOP/s Double Precision MFLOP/s + diff --git a/collectors/likwid/groups/atom/FLOPS_X87.txt b/collectors/likwid/groups/atom/FLOPS_X87.txt new file mode 100644 index 0000000..58c5d42 --- /dev/null +++ b/collectors/likwid/groups/atom/FLOPS_X87.txt @@ -0,0 +1,19 @@ +SHORT X87 MFLOP/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +PMC0 X87_COMP_OPS_EXE_ANY_AR + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +CPI FIXC1/FIXC0 +X87 [MFLOP/s] 1.0E-06*PMC0/time + +LONG +Formulas: +X87 [MFLOP/s] = 1.0E-06*X87_COMP_OPS_EXE_ANY_AR/runtime +-- +The MFLOP/s made with X87 instructions + diff --git a/collectors/likwid/groups/atom/MEM.txt b/collectors/likwid/groups/atom/MEM.txt new file mode 100644 index 0000000..355b7fd --- /dev/null +++ b/collectors/likwid/groups/atom/MEM.txt @@ -0,0 +1,21 @@ +SHORT Main memory bandwidth in MBytes/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +PMC0 BUS_TRANS_MEM_THIS_CORE_THIS_A + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +CPI FIXC1/FIXC0 +Memory bandwidth [MBytes/s] 1.0E-06*PMC0*64.0/time +Memory data volume [GBytes] 1.0E-09*PMC0*64.0 + +LONG +Formulas: +Memory bandwidth [MBytes/s] = 1.0E-06*BUS_TRANS_MEM_THIS_CORE_THIS_A*64/time +Memory data volume [GBytes] = 1.0E-09*BUS_TRANS_MEM_THIS_CORE_THIS_A*64.0 +- +Profiling group to measure memory bandwidth drawn by this core. + diff --git a/collectors/likwid/groups/atom/TLB.txt b/collectors/likwid/groups/atom/TLB.txt new file mode 100644 index 0000000..5d0aa1b --- /dev/null +++ b/collectors/likwid/groups/atom/TLB.txt @@ -0,0 +1,21 @@ +SHORT TLB miss rate + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +PMC0 DATA_TLB_MISSES_DTLB_MISS + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +CPI FIXC1/FIXC0 +DTLB misses PMC0 +DTLB miss rate PMC0/FIXC0 + +LONG +Formulas: +DTLB misses = DATA_TLB_MISSES_DTLB_MISS +DTLB miss rate = DATA_TLB_MISSES_DTLB_MISS/INSTR_RETIRED_ANY +-- +The DTLB miss rate gives a measure how often a TLB miss occurred per instruction. + diff --git a/collectors/likwid/groups/broadwell/BRANCH.txt b/collectors/likwid/groups/broadwell/BRANCH.txt new file mode 100644 index 0000000..b8d41b2 --- /dev/null +++ b/collectors/likwid/groups/broadwell/BRANCH.txt @@ -0,0 +1,31 @@ +SHORT Branch prediction miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 BR_INST_RETIRED_ALL_BRANCHES +PMC1 BR_MISP_RETIRED_ALL_BRANCHES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Branch rate PMC0/FIXC0 +Branch misprediction rate PMC1/FIXC0 +Branch misprediction ratio PMC1/PMC0 +Instructions per branch FIXC0/PMC0 + +LONG +Formulas: +Branch rate = BR_INST_RETIRED_ALL_BRANCHES/INSTR_RETIRED_ANY +Branch misprediction rate = BR_MISP_RETIRED_ALL_BRANCHES/INSTR_RETIRED_ANY +Branch misprediction ratio = BR_MISP_RETIRED_ALL_BRANCHES/BR_INST_RETIRED_ALL_BRANCHES +Instructions per branch = INSTR_RETIRED_ANY/BR_INST_RETIRED_ALL_BRANCHES +- +The rates state how often on average a branch or a mispredicted branch occurred +per instruction retired in total. The branch misprediction ratio sets directly +into relation what ratio of all branch instruction where mispredicted. +Instructions per branch is 1/branch rate. + diff --git a/collectors/likwid/groups/broadwell/CLOCK.txt b/collectors/likwid/groups/broadwell/CLOCK.txt new file mode 100644 index 0000000..b81bee6 --- /dev/null +++ b/collectors/likwid/groups/broadwell/CLOCK.txt @@ -0,0 +1,26 @@ +SHORT Power and Energy consumption + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PWR0 PWR_PKG_ENERGY +UBOXFIX UNCORE_CLOCK + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +Uncore Clock [MHz] 1.E-06*UBOXFIX/time +CPI FIXC1/FIXC0 +Energy [J] PWR0 +Power [W] PWR0/time + +LONG +Formulas: +Power = PWR_PKG_ENERGY / time +Uncore Clock [MHz] = 1.E-06 * UNCORE_CLOCK / time +- +Broadwell implements the new RAPL interface. This interface enables to +monitor the consumed energy on the package (socket) level. + diff --git a/collectors/likwid/groups/broadwell/CYCLE_ACTIVITY.txt b/collectors/likwid/groups/broadwell/CYCLE_ACTIVITY.txt new file mode 100644 index 0000000..c432a44 --- /dev/null +++ b/collectors/likwid/groups/broadwell/CYCLE_ACTIVITY.txt @@ -0,0 +1,38 @@ +SHORT Cycle Activities + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 CYCLE_ACTIVITY_CYCLES_L2_PENDING +PMC1 CYCLE_ACTIVITY_CYCLES_LDM_PENDING +PMC2 CYCLE_ACTIVITY_CYCLES_L1D_PENDING +PMC3 CYCLE_ACTIVITY_CYCLES_NO_EXECUTE + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Cycles without execution [%] (PMC3/FIXC1)*100 +Cycles without execution due to L1D [%] (PMC2/FIXC1)*100 +Cycles without execution due to L2 [%] (PMC0/FIXC1)*100 +Cycles without execution due to memory loads [%] (PMC1/FIXC1)*100 + +LONG +Formulas: +Cycles without execution [%] = CYCLE_ACTIVITY_CYCLES_NO_EXECUTE/CPU_CLK_UNHALTED_CORE*100 +Cycles with stalls due to L1D [%] = CYCLE_ACTIVITY_CYCLES_L1D_PENDING/CPU_CLK_UNHALTED_CORE*100 +Cycles with stalls due to L2 [%] = CYCLE_ACTIVITY_CYCLES_L2_PENDING/CPU_CLK_UNHALTED_CORE*100 +Cycles without execution due to memory loads [%] = CYCLE_ACTIVITY_CYCLES_LDM_PENDING/CPU_CLK_UNHALTED_CORE*100 +-- +This performance group measures the cycles while waiting for data from the cache +and memory hierarchy. +CYCLE_ACTIVITY_CYCLES_NO_EXECUTE: Counts number of cycles nothing is executed on +any execution port. +CYCLE_ACTIVITY_CYCLES_L1D_PENDING: Cycles while L1 cache miss demand load is +outstanding. +CYCLE_ACTIVITY_CYCLES_L2_PENDING: Cycles while L2 cache miss demand load is +outstanding. +CYCLE_ACTIVITY_CYCLES_LDM_PENDING: Cycles while memory subsystem has an +outstanding load. diff --git a/collectors/likwid/groups/broadwell/CYCLE_STALLS.txt b/collectors/likwid/groups/broadwell/CYCLE_STALLS.txt new file mode 100644 index 0000000..795aeb9 --- /dev/null +++ b/collectors/likwid/groups/broadwell/CYCLE_STALLS.txt @@ -0,0 +1,45 @@ +SHORT Cycle Activities (Stalls) + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 CYCLE_ACTIVITY_STALLS_L2_PENDING +PMC1 CYCLE_ACTIVITY_STALLS_LDM_PENDING +PMC2 CYCLE_ACTIVITY_STALLS_L1D_PENDING +PMC3 CYCLE_ACTIVITY_STALLS_TOTAL + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Total execution stalls PMC3 +Stalls caused by L1D misses [%] (PMC2/PMC3)*100 +Stalls caused by L2 misses [%] (PMC0/PMC3)*100 +Stalls caused by memory loads [%] (PMC1/PMC3)*100 +Execution stall rate [%] (PMC3/FIXC1)*100 +Stalls caused by L1D misses rate [%] (PMC2/FIXC1)*100 +Stalls caused by L2 misses rate [%] (PMC0/FIXC1)*100 +Stalls caused by memory loads rate [%] (PMC1/FIXC1)*100 + +LONG +Formulas: +Total execution stalls = CYCLE_ACTIVITY_STALLS_TOTAL +Stalls caused by L1D misses [%] = (CYCLE_ACTIVITY_STALLS_L1D_PENDING/CYCLE_ACTIVITY_STALLS_TOTAL)*100 +Stalls caused by L2 misses [%] = (CYCLE_ACTIVITY_STALLS_L2_PENDING/CYCLE_ACTIVITY_STALLS_TOTAL)*100 +Stalls caused by memory loads [%] = (CYCLE_ACTIVITY_STALLS_LDM_PENDING/CYCLE_ACTIVITY_STALLS_TOTAL)*100 +Execution stall rate [%] = (CYCLE_ACTIVITY_STALLS_TOTAL/CPU_CLK_UNHALTED_CORE)*100 +Stalls caused by L1D misses rate [%] = (CYCLE_ACTIVITY_STALLS_L1D_PENDING/CPU_CLK_UNHALTED_CORE)*100 +Stalls caused by L2 misses rate [%] = (CYCLE_ACTIVITY_STALLS_L2_PENDING/CPU_CLK_UNHALTED_CORE)*100 +Stalls caused by memory loads rate [%] = (CYCLE_ACTIVITY_STALLS_LDM_PENDING/CPU_CLK_UNHALTED_CORE)*100 +-- +This performance group measures the stalls caused by data traffic in the cache +hierarchy. +CYCLE_ACTIVITY_STALLS_TOTAL: Total execution stalls. +CYCLE_ACTIVITY_STALLS_L1D_PENDING: Execution stalls while L1 cache miss demand +load is outstanding. +CYCLE_ACTIVITY_STALLS_L2_PENDING: Execution stalls while L2 cache miss demand +load is outstanding. +CYCLE_ACTIVITY_STALLS_LDM_PENDING: Execution stalls while memory subsystem has +an outstanding load. diff --git a/collectors/likwid/groups/broadwell/DATA.txt b/collectors/likwid/groups/broadwell/DATA.txt new file mode 100644 index 0000000..6955eb7 --- /dev/null +++ b/collectors/likwid/groups/broadwell/DATA.txt @@ -0,0 +1,22 @@ +SHORT Load to store ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 MEM_UOPS_RETIRED_LOADS_ALL +PMC1 MEM_UOPS_RETIRED_STORES_ALL + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Load to store ratio PMC0/PMC1 + +LONG +Formulas: +Load to store ratio = MEM_UOPS_RETIRED_LOADS_ALL/MEM_UOPS_RETIRED_STORES_ALL +- +This is a metric to determine your load to store ratio. + diff --git a/collectors/likwid/groups/broadwell/DIVIDE.txt b/collectors/likwid/groups/broadwell/DIVIDE.txt new file mode 100644 index 0000000..c7c5fb2 --- /dev/null +++ b/collectors/likwid/groups/broadwell/DIVIDE.txt @@ -0,0 +1,24 @@ +SHORT Divide unit information + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0:EDGEDETECT ARITH_FPU_DIV_ACTIVE +PMC1 ARITH_FPU_DIV_ACTIVE + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Number of divide ops PMC0:EDGEDETECT +Avg. divide unit usage duration PMC1/PMC0:EDGEDETECT + +LONG +Formulas: +Number of divide ops = ARITH_FPU_DIV_ACTIVE:EDGEDETECT +Avg. divide unit usage duration = ARITH_FPU_DIV_ACTIVE/ARITH_FPU_DIV_ACTIVE:EDGEDETECT +- +This performance group measures the average latency of divide operations diff --git a/collectors/likwid/groups/broadwell/ENERGY.txt b/collectors/likwid/groups/broadwell/ENERGY.txt new file mode 100644 index 0000000..09eaeb1 --- /dev/null +++ b/collectors/likwid/groups/broadwell/ENERGY.txt @@ -0,0 +1,39 @@ +SHORT Power and Energy consumption + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +TMP0 TEMP_CORE +PWR0 PWR_PKG_ENERGY +PWR1 PWR_PP0_ENERGY +PWR2 PWR_PP1_ENERGY +PWR3 PWR_DRAM_ENERGY + + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Temperature [C] TMP0 +Energy [J] PWR0 +Power [W] PWR0/time +Energy PP0 [J] PWR1 +Power PP0 [W] PWR1/time +Energy PP1 [J] PWR2 +Power PP1 [W] PWR2/time +Energy DRAM [J] PWR3 +Power DRAM [W] PWR3/time + +LONG +Formulas: +Power = PWR_PKG_ENERGY / time +Power PP0 = PWR_PP0_ENERGY / time +Power PP1 = PWR_PP1_ENERGY / time +Power DRAM = PWR_DRAM_ENERGY / time +- +Broadwell implements the new RAPL interface. This interface enables to +monitor the consumed energy on the package (socket) and DRAM level. + diff --git a/collectors/likwid/groups/broadwell/FALSE_SHARE.txt b/collectors/likwid/groups/broadwell/FALSE_SHARE.txt new file mode 100644 index 0000000..a297654 --- /dev/null +++ b/collectors/likwid/groups/broadwell/FALSE_SHARE.txt @@ -0,0 +1,25 @@ +SHORT False sharing + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 MEM_LOAD_UOPS_L3_HIT_RETIRED_XSNP_HITM +PMC2 MEM_UOPS_RETIRED_LOADS_ALL + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Local LLC false sharing [MByte] 1.E-06*PMC0*64 +Local LLC false sharing rate PMC0/PMC2 + +LONG +Formulas: +Local LLC false sharing [MByte] = 1.E-06*MEM_LOAD_UOPS_L3_HIT_RETIRED_XSNP_HITM*64 +Local LLC false sharing rate = MEM_LOAD_UOPS_L3_HIT_RETIRED_XSNP_HITM/MEM_UOPS_RETIRED_LOADS_ALL +- +False-sharing of cache lines can dramatically reduce the performance of an +application. This performance group measures the L3 traffic induced by false-sharing. +The false-sharing rate uses all memory load UOPs as reference. diff --git a/collectors/likwid/groups/broadwell/FLOPS_AVX.txt b/collectors/likwid/groups/broadwell/FLOPS_AVX.txt new file mode 100644 index 0000000..7854608 --- /dev/null +++ b/collectors/likwid/groups/broadwell/FLOPS_AVX.txt @@ -0,0 +1,24 @@ +SHORT Packed AVX MFLOP/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE +PMC1 FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Packed SP [MFLOP/s] 1.0E-06*(PMC0*8.0)/time +Packed DP [MFLOP/s] 1.0E-06*(PMC1*4.0)/time + +LONG +Formulas: +Packed SP [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE*8)/runtime +Packed DP [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE*4)/runtime +- +FLOP rates of 256 bit packed floating-point instructions + diff --git a/collectors/likwid/groups/broadwell/FLOPS_DP.txt b/collectors/likwid/groups/broadwell/FLOPS_DP.txt new file mode 100644 index 0000000..348ec76 --- /dev/null +++ b/collectors/likwid/groups/broadwell/FLOPS_DP.txt @@ -0,0 +1,31 @@ +SHORT Double Precision MFLOP/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 FP_ARITH_INST_RETIRED_128B_PACKED_DOUBLE +PMC1 FP_ARITH_INST_RETIRED_SCALAR_DOUBLE +PMC2 FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +DP [MFLOP/s] 1.0E-06*(PMC0*2.0+PMC1+PMC2*4.0)/time +AVX DP [MFLOP/s] 1.0E-06*(PMC2*4.0)/time +Packed [MUOPS/s] 1.0E-06*(PMC0+PMC2)/time +Scalar [MUOPS/s] 1.0E-06*PMC1/time +Vectorization ratio 100*(PMC0+PMC2)/(PMC0+PMC1+PMC2) + +LONG +Formulas: +DP [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_128B_PACKED_DOUBLE*2+FP_ARITH_INST_RETIRED_SCALAR_DOUBLE+FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE*4)/runtime +AVX DP [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE*4)/runtime +Packed [MUOPS/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_128B_PACKED_DOUBLE+FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE)/runtime +Scalar [MUOPS/s] = 1.0E-06*FP_ARITH_INST_RETIRED_SCALAR_DOUBLE/runtime +Vectorization ratio = 100*(FP_ARITH_INST_RETIRED_128B_PACKED_DOUBLE+FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE)/(FP_ARITH_INST_RETIRED_SCALAR_DOUBLE+FP_ARITH_INST_RETIRED_128B_PACKED_DOUBLE+FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE) +- +AVX/SSE scalar and packed double precision FLOP rates. + diff --git a/collectors/likwid/groups/broadwell/FLOPS_SP.txt b/collectors/likwid/groups/broadwell/FLOPS_SP.txt new file mode 100644 index 0000000..1d7fd7c --- /dev/null +++ b/collectors/likwid/groups/broadwell/FLOPS_SP.txt @@ -0,0 +1,31 @@ +SHORT Single Precision MFLOP/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 FP_ARITH_INST_RETIRED_128B_PACKED_SINGLE +PMC1 FP_ARITH_INST_RETIRED_SCALAR_SINGLE +PMC2 FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +SP [MFLOP/s] 1.0E-06*(PMC0*4.0+PMC1+PMC2*8.0)/time +AVX SP [MFLOP/s] 1.0E-06*(PMC2*8.0)/time +Packed [MUOPS/s] 1.0E-06*(PMC0+PMC2)/time +Scalar [MUOPS/s] 1.0E-06*PMC1/time +Vectorization ratio 100*(PMC0+PMC2)/(PMC0+PMC1+PMC2) + +LONG +Formulas: +SP [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_128B_PACKED_SINGLE*4+FP_ARITH_INST_RETIRED_SCALAR_SINGLE+FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE*8)/runtime +AVX SP [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE*8)/runtime +Packed [MUOPS/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_128B_PACKED_SINGLE+FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE)/runtime +Scalar [MUOPS/s] = 1.0E-06*FP_ARITH_INST_RETIRED_SCALAR_SINGLE/runtime +Vectorization ratio [%] = 100*(FP_ARITH_INST_RETIRED_128B_PACKED_SINGLE+FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE)/(FP_ARITH_INST_RETIRED_SCALAR_SINGLE+FP_ARITH_INST_RETIRED_128B_PACKED_SINGLE+FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE) +- +AVX/SSE scalar and packed single precision FLOP rates. + diff --git a/collectors/likwid/groups/broadwell/ICACHE.txt b/collectors/likwid/groups/broadwell/ICACHE.txt new file mode 100644 index 0000000..5f11ad6 --- /dev/null +++ b/collectors/likwid/groups/broadwell/ICACHE.txt @@ -0,0 +1,25 @@ +SHORT Instruction cache miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 ICACHE_ACCESSES +PMC1 ICACHE_MISSES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L1I request rate PMC0/FIXC0 +L1I miss rate PMC1/FIXC0 +L1I miss ratio PMC1/PMC0 + +LONG +Formulas: +L1I request rate = ICACHE_ACCESSES / INSTR_RETIRED_ANY +L1I miss rate = ICACHE_MISSES / INSTR_RETIRED_ANY +L1I miss ratio = ICACHE_MISSES / ICACHE_ACCESSES +- +This group measures some L1 instruction cache metrics. diff --git a/collectors/likwid/groups/broadwell/L2.txt b/collectors/likwid/groups/broadwell/L2.txt new file mode 100644 index 0000000..60c7f79 --- /dev/null +++ b/collectors/likwid/groups/broadwell/L2.txt @@ -0,0 +1,37 @@ +SHORT L2 cache bandwidth in MBytes/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 L1D_REPLACEMENT +PMC1 L2_TRANS_L1D_WB +PMC2 ICACHE_MISSES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L2D load bandwidth [MBytes/s] 1.0E-06*PMC0*64.0/time +L2D load data volume [GBytes] 1.0E-09*PMC0*64.0 +L2D evict bandwidth [MBytes/s] 1.0E-06*PMC1*64.0/time +L2D evict data volume [GBytes] 1.0E-09*PMC1*64.0 +L2 bandwidth [MBytes/s] 1.0E-06*(PMC0+PMC1+PMC2)*64.0/time +L2 data volume [GBytes] 1.0E-09*(PMC0+PMC1+PMC2)*64.0 + +LONG +Formulas: +L2D load bandwidth [MBytes/s] = 1.0E-06*L1D_REPLACEMENT*64.0/time +L2D load data volume [GBytes] = 1.0E-09*L1D_REPLACEMENT*64.0 +L2D evict bandwidth [MBytes/s] = 1.0E-06*L2_TRANS_L1D_WB*64.0/time +L2D evict data volume [GBytes] = 1.0E-09*L2_TRANS_L1D_WB*64.0 +L2 bandwidth [MBytes/s] = 1.0E-06*(L1D_REPLACEMENT+L2_TRANS_L1D_WB+ICACHE_MISSES)*64.0/time +L2 data volume [GBytes] = 1.0E-09*(L1D_REPLACEMENT+L2_TRANS_L1D_WB+ICACHE_MISSES)*64.0 +- +Profiling group to measure L2 cache bandwidth. The bandwidth is computed by the +number of cache line loaded from the L2 to the L2 data cache and the writebacks from +the L2 data cache to the L2 cache. The group also outputs total data volume transferred between +L2 and L1. Note that this bandwidth also includes data transfers due to a write +allocate load on a store miss in L1 and cache lines transferred it the instruction +cache. diff --git a/collectors/likwid/groups/broadwell/L2CACHE.txt b/collectors/likwid/groups/broadwell/L2CACHE.txt new file mode 100644 index 0000000..9b5dd4b --- /dev/null +++ b/collectors/likwid/groups/broadwell/L2CACHE.txt @@ -0,0 +1,34 @@ +SHORT L2 cache miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 L2_TRANS_ALL_REQUESTS +PMC1 L2_RQSTS_MISS + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L2 request rate PMC0/FIXC0 +L2 miss rate PMC1/FIXC0 +L2 miss ratio PMC1/PMC0 + +LONG +Formulas: +L2 request rate = L2_TRANS_ALL_REQUESTS/INSTR_RETIRED_ANY +L2 miss rate = L2_RQSTS_MISS/INSTR_RETIRED_ANY +L2 miss ratio = L2_RQSTS_MISS/L2_TRANS_ALL_REQUESTS +- +This group measures the locality of your data accesses with regard to the +L2 cache. L2 request rate tells you how data intensive your code is +or how many data accesses you have on average per instruction. +The L2 miss rate gives a measure how often it was necessary to get +cache lines from memory. And finally L2 miss ratio tells you how many of your +memory references required a cache line to be loaded from a higher level. +While the# data cache miss rate might be given by your algorithm you should +try to get data cache miss ratio as low as possible by increasing your cache reuse. + + diff --git a/collectors/likwid/groups/broadwell/L3.txt b/collectors/likwid/groups/broadwell/L3.txt new file mode 100644 index 0000000..98d1d9e --- /dev/null +++ b/collectors/likwid/groups/broadwell/L3.txt @@ -0,0 +1,36 @@ +SHORT L3 cache bandwidth in MBytes/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 L2_LINES_IN_ALL +PMC1 L2_TRANS_L2_WB + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L3 load bandwidth [MBytes/s] 1.0E-06*PMC0*64.0/time +L3 load data volume [GBytes] 1.0E-09*PMC0*64.0 +L3 evict bandwidth [MBytes/s] 1.0E-06*PMC1*64.0/time +L3 evict data volume [GBytes] 1.0E-09*PMC1*64.0 +L3 bandwidth [MBytes/s] 1.0E-06*(PMC0+PMC1)*64.0/time +L3 data volume [GBytes] 1.0E-09*(PMC0+PMC1)*64.0 + +LONG +Formulas: +L3 load bandwidth [MBytes/s] = 1.0E-06*L2_LINES_IN_ALL*64.0/time +L3 load data volume [GBytes] = 1.0E-09*L2_LINES_IN_ALL*64.0 +L3 evict bandwidth [MBytes/s] = 1.0E-06*L2_TRANS_L2_WB*64.0/time +L3 evict data volume [GBytes] = 1.0E-09*L2_TRANS_L2_WB*64.0 +L3 bandwidth [MBytes/s] = 1.0E-06*(L2_LINES_IN_ALL+L2_TRANS_L2_WB)*64/time +L3 data volume [GBytes] = 1.0E-09*(L2_LINES_IN_ALL+L2_TRANS_L2_WB)*64 +- +Profiling group to measure L3 cache bandwidth. The bandwidth is computed by the +number of cache line allocated in the L2 and the number of modified cache lines +evicted from the L2. This group also output data volume transferred between the +L3 and measured cores L2 caches. Note that this bandwidth also includes data +transfers due to a write allocate load on a store miss in L2. + diff --git a/collectors/likwid/groups/broadwell/L3CACHE.txt b/collectors/likwid/groups/broadwell/L3CACHE.txt new file mode 100644 index 0000000..f863daa --- /dev/null +++ b/collectors/likwid/groups/broadwell/L3CACHE.txt @@ -0,0 +1,35 @@ +SHORT L3 cache miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 MEM_LOAD_UOPS_RETIRED_L3_ALL +PMC1 MEM_LOAD_UOPS_RETIRED_L3_MISS +PMC2 UOPS_RETIRED_ALL + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L3 request rate PMC0/PMC2 +L3 miss rate PMC1/PMC2 +L3 miss ratio PMC1/PMC0 + +LONG +Formulas: +L3 request rate = MEM_LOAD_UOPS_RETIRED_L3_ALL/UOPS_RETIRED_ALL +L3 miss rate = MEM_LOAD_UOPS_RETIRED_L3_MISS/UOPS_RETIRED_ALL +L3 miss ratio = MEM_LOAD_UOPS_RETIRED_L3_MISS/MEM_LOAD_UOPS_RETIRED_L3_ALL +- +This group measures the locality of your data accesses with regard to the +L3 cache. L3 request rate tells you how data intensive your code is +or how many data accesses you have on average per instruction. +The L3 miss rate gives a measure how often it was necessary to get +cache lines from memory. And finally L3 miss ratio tells you how many of your +memory references required a cache line to be loaded from a higher level. +While the# data cache miss rate might be given by your algorithm you should +try to get data cache miss ratio as low as possible by increasing your cache reuse. + + diff --git a/collectors/likwid/groups/broadwell/PORT_USAGE.txt b/collectors/likwid/groups/broadwell/PORT_USAGE.txt new file mode 100644 index 0000000..298df1d --- /dev/null +++ b/collectors/likwid/groups/broadwell/PORT_USAGE.txt @@ -0,0 +1,50 @@ +SHORT Execution port utilization + +REQUIRE_NOHT + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 UOPS_EXECUTED_PORT_PORT_0 +PMC1 UOPS_EXECUTED_PORT_PORT_1 +PMC2 UOPS_EXECUTED_PORT_PORT_2 +PMC3 UOPS_EXECUTED_PORT_PORT_3 +PMC4 UOPS_EXECUTED_PORT_PORT_4 +PMC5 UOPS_EXECUTED_PORT_PORT_5 +PMC6 UOPS_EXECUTED_PORT_PORT_6 +PMC7 UOPS_EXECUTED_PORT_PORT_7 + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Port0 usage ratio PMC0/(PMC0+PMC1+PMC2+PMC3+PMC4+PMC5+PMC6+PMC7) +Port1 usage ratio PMC1/(PMC0+PMC1+PMC2+PMC3+PMC4+PMC5+PMC6+PMC7) +Port2 usage ratio PMC2/(PMC0+PMC1+PMC2+PMC3+PMC4+PMC5+PMC6+PMC7) +Port3 usage ratio PMC3/(PMC0+PMC1+PMC2+PMC3+PMC4+PMC5+PMC6+PMC7) +Port4 usage ratio PMC4/(PMC0+PMC1+PMC2+PMC3+PMC4+PMC5+PMC6+PMC7) +Port5 usage ratio PMC5/(PMC0+PMC1+PMC2+PMC3+PMC4+PMC5+PMC6+PMC7) +Port6 usage ratio PMC6/(PMC0+PMC1+PMC2+PMC3+PMC4+PMC5+PMC6+PMC7) +Port7 usage ratio PMC7/(PMC0+PMC1+PMC2+PMC3+PMC4+PMC5+PMC6+PMC7) + +LONG +Formulas: +Port0 usage ratio = UOPS_EXECUTED_PORT_PORT_0/SUM(UOPS_EXECUTED_PORT_PORT_*) +Port1 usage ratio = UOPS_EXECUTED_PORT_PORT_1/SUM(UOPS_EXECUTED_PORT_PORT_*) +Port2 usage ratio = UOPS_EXECUTED_PORT_PORT_2/SUM(UOPS_EXECUTED_PORT_PORT_*) +Port3 usage ratio = UOPS_EXECUTED_PORT_PORT_3/SUM(UOPS_EXECUTED_PORT_PORT_*) +Port4 usage ratio = UOPS_EXECUTED_PORT_PORT_4/SUM(UOPS_EXECUTED_PORT_PORT_*) +Port5 usage ratio = UOPS_EXECUTED_PORT_PORT_5/SUM(UOPS_EXECUTED_PORT_PORT_*) +Port6 usage ratio = UOPS_EXECUTED_PORT_PORT_6/SUM(UOPS_EXECUTED_PORT_PORT_*) +Port7 usage ratio = UOPS_EXECUTED_PORT_PORT_7/SUM(UOPS_EXECUTED_PORT_PORT_*) +- +This group measures the execution port utilization in a CPU core. The group can +only be measured when HyperThreading is disabled because only then each CPU core +can program eight counters. +Please be aware that the counters PMC4-7 are broken on Intel Broadwell. They +don't increment if either user- or kernel-level filtering is applied. User-level +filtering is default in LIKWID, hence kernel-level filtering is added +automatically for PMC4-7. The returned counts can be much higher. diff --git a/collectors/likwid/groups/broadwell/RECOVERY.txt b/collectors/likwid/groups/broadwell/RECOVERY.txt new file mode 100644 index 0000000..7928ee4 --- /dev/null +++ b/collectors/likwid/groups/broadwell/RECOVERY.txt @@ -0,0 +1,22 @@ +SHORT Recovery duration + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 INT_MISC_RECOVERY_CYCLES +PMC1 INT_MISC_RECOVERY_COUNT + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Avg. recovery duration PMC0/PMC1 + +LONG +Formulas: +Avg. recovery duration = INT_MISC_RECOVERY_CYCLES/INT_MISC_RECOVERY_COUNT +- +This group measures the duration of recoveries after SSE exception, memory +disambiguation, etc... diff --git a/collectors/likwid/groups/broadwell/TLB_DATA.txt b/collectors/likwid/groups/broadwell/TLB_DATA.txt new file mode 100644 index 0000000..8d94e05 --- /dev/null +++ b/collectors/likwid/groups/broadwell/TLB_DATA.txt @@ -0,0 +1,35 @@ +SHORT L2 data TLB miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 DTLB_LOAD_MISSES_CAUSES_A_WALK +PMC1 DTLB_STORE_MISSES_CAUSES_A_WALK +PMC2 DTLB_LOAD_MISSES_WALK_DURATION +PMC3 DTLB_STORE_MISSES_WALK_DURATION + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L1 DTLB load misses PMC0 +L1 DTLB load miss rate PMC0/FIXC0 +L1 DTLB load miss duration [Cyc] PMC2/PMC0 +L1 DTLB store misses PMC1 +L1 DTLB store miss rate PMC1/FIXC0 +L1 DTLB store miss duration [Cyc] PMC3/PMC1 + +LONG +Formulas: +L1 DTLB load misses = DTLB_LOAD_MISSES_CAUSES_A_WALK +L1 DTLB load miss rate = DTLB_LOAD_MISSES_CAUSES_A_WALK / INSTR_RETIRED_ANY +L1 DTLB load miss duration [Cyc] = DTLB_LOAD_MISSES_WALK_DURATION / DTLB_LOAD_MISSES_CAUSES_A_WALK +L1 DTLB store misses = DTLB_STORE_MISSES_CAUSES_A_WALK +L1 DTLB store miss rate = DTLB_STORE_MISSES_CAUSES_A_WALK / INSTR_RETIRED_ANY +L1 DTLB store miss duration [Cyc] = DTLB_STORE_MISSES_WALK_DURATION / DTLB_STORE_MISSES_CAUSES_A_WALK +- +The DTLB load and store miss rates gives a measure how often a TLB miss occurred +per instruction. The duration measures the time in cycles how long a walk did take. + diff --git a/collectors/likwid/groups/broadwell/TLB_INSTR.txt b/collectors/likwid/groups/broadwell/TLB_INSTR.txt new file mode 100644 index 0000000..235d977 --- /dev/null +++ b/collectors/likwid/groups/broadwell/TLB_INSTR.txt @@ -0,0 +1,28 @@ +SHORT L1 Instruction TLB miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 ITLB_MISSES_CAUSES_A_WALK +PMC1 ITLB_MISSES_WALK_DURATION + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L1 ITLB misses PMC0 +L1 ITLB miss rate PMC0/FIXC0 +L1 ITLB miss duration [Cyc] PMC1/PMC0 + + +LONG +Formulas: +L1 ITLB misses = ITLB_MISSES_CAUSES_A_WALK +L1 ITLB miss rate = ITLB_MISSES_CAUSES_A_WALK / INSTR_RETIRED_ANY +L1 ITLB miss duration [Cyc] = ITLB_MISSES_WALK_DURATION / ITLB_MISSES_CAUSES_A_WALK +- +The ITLB miss rates gives a measure how often a TLB miss occurred +per instruction. The duration measures the time in cycles how long a walk did take. + diff --git a/collectors/likwid/groups/broadwell/TMA.txt b/collectors/likwid/groups/broadwell/TMA.txt new file mode 100644 index 0000000..afb4126 --- /dev/null +++ b/collectors/likwid/groups/broadwell/TMA.txt @@ -0,0 +1,48 @@ +SHORT Top down cycle allocation + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 UOPS_ISSUED_ANY +PMC1 UOPS_RETIRED_RETIRE_SLOTS +PMC2 IDQ_UOPS_NOT_DELIVERED_CORE +PMC3 INT_MISC_RECOVERY_CYCLES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +IPC FIXC0/FIXC1 +Total Slots 4*FIXC1 +Slots Retired PMC1 +Fetch Bubbles PMC2 +Recovery Bubbles 4*PMC3 +Front End [%] PMC2/(4*FIXC1)*100 +Speculation [%] (PMC0-PMC1+(4*PMC3))/(4*FIXC1)*100 +Retiring [%] PMC1/(4*FIXC1)*100 +Back End [%] (1-((PMC2+PMC0+(4*PMC3))/(4*FIXC1)))*100 + +LONG +Formulas: +Total Slots = 4*CPU_CLK_UNHALTED_CORE +Slots Retired = UOPS_RETIRED_RETIRE_SLOTS +Fetch Bubbles = IDQ_UOPS_NOT_DELIVERED_CORE +Recovery Bubbles = 4*INT_MISC_RECOVERY_CYCLES +Front End [%] = IDQ_UOPS_NOT_DELIVERED_CORE/(4*CPU_CLK_UNHALTED_CORE)*100 +Speculation [%] = (UOPS_ISSUED_ANY-UOPS_RETIRED_RETIRE_SLOTS+(4*INT_MISC_RECOVERY_CYCLES))/(4*CPU_CLK_UNHALTED_CORE)*100 +Retiring [%] = UOPS_RETIRED_RETIRE_SLOTS/(4*CPU_CLK_UNHALTED_CORE)*100 +Back End [%] = (1-((IDQ_UOPS_NOT_DELIVERED_CORE+UOPS_ISSUED_ANY+(4*INT_MISC_RECOVERY_CYCLES))/(4*CPU_CLK_UNHALTED_CORE)))*100 +-- +This performance group measures cycles to determine percentage of time spent in +front end, back end, retiring and speculation. These metrics are published and +verified by Intel. Further information: +Webpage describing Top-Down Method and its usage in Intel vTune: +https://software.intel.com/en-us/vtune-amplifier-help-tuning-applications-using-a-top-down-microarchitecture-analysis-method +Paper by Yasin Ahmad: +https://sites.google.com/site/analysismethods/yasin-pubs/TopDown-Yasin-ISPASS14.pdf?attredirects=0 +Slides by Yasin Ahmad: +http://www.cs.technion.ac.il/~erangi/TMA_using_Linux_perf__Ahmad_Yasin.pdf +The performance group was originally published here: +http://perf.mvermeulen.com/2018/04/14/top-down-performance-counter-analysis-part-1-likwid/ diff --git a/collectors/likwid/groups/broadwell/UOPS.txt b/collectors/likwid/groups/broadwell/UOPS.txt new file mode 100644 index 0000000..e6cc208 --- /dev/null +++ b/collectors/likwid/groups/broadwell/UOPS.txt @@ -0,0 +1,35 @@ +SHORT UOPs execution info + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 UOPS_ISSUED_ANY +PMC1 UOPS_EXECUTED_THREAD +PMC2 UOPS_RETIRED_ALL +PMC3 UOPS_ISSUED_FLAGS_MERGE + + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Issued UOPs PMC0 +Merged UOPs PMC3 +Executed UOPs PMC1 +Retired UOPs PMC2 + +LONG +Formulas: +Issued UOPs = UOPS_ISSUED_ANY +Merged UOPs = UOPS_ISSUED_FLAGS_MERGE +Executed UOPs = UOPS_EXECUTED_THREAD +Retired UOPs = UOPS_RETIRED_ALL +- +This group returns information about the instruction pipeline. It measures the +issued, executed and retired uOPs and returns the number of uOPs which were issued +but not executed as well as the number of uOPs which were executed but never retired. +The executed but not retired uOPs commonly come from speculatively executed branches. + diff --git a/collectors/likwid/groups/broadwellD/BRANCH.txt b/collectors/likwid/groups/broadwellD/BRANCH.txt new file mode 100644 index 0000000..b8d41b2 --- /dev/null +++ b/collectors/likwid/groups/broadwellD/BRANCH.txt @@ -0,0 +1,31 @@ +SHORT Branch prediction miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 BR_INST_RETIRED_ALL_BRANCHES +PMC1 BR_MISP_RETIRED_ALL_BRANCHES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Branch rate PMC0/FIXC0 +Branch misprediction rate PMC1/FIXC0 +Branch misprediction ratio PMC1/PMC0 +Instructions per branch FIXC0/PMC0 + +LONG +Formulas: +Branch rate = BR_INST_RETIRED_ALL_BRANCHES/INSTR_RETIRED_ANY +Branch misprediction rate = BR_MISP_RETIRED_ALL_BRANCHES/INSTR_RETIRED_ANY +Branch misprediction ratio = BR_MISP_RETIRED_ALL_BRANCHES/BR_INST_RETIRED_ALL_BRANCHES +Instructions per branch = INSTR_RETIRED_ANY/BR_INST_RETIRED_ALL_BRANCHES +- +The rates state how often on average a branch or a mispredicted branch occurred +per instruction retired in total. The branch misprediction ratio sets directly +into relation what ratio of all branch instruction where mispredicted. +Instructions per branch is 1/branch rate. + diff --git a/collectors/likwid/groups/broadwellD/CACHES.txt b/collectors/likwid/groups/broadwellD/CACHES.txt new file mode 100644 index 0000000..275e30f --- /dev/null +++ b/collectors/likwid/groups/broadwellD/CACHES.txt @@ -0,0 +1,123 @@ +SHORT Cache bandwidth in MBytes/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 L1D_REPLACEMENT +PMC1 L2_TRANS_L1D_WB +PMC2 L2_LINES_IN_ALL +PMC3 L2_TRANS_L2_WB +CBOX0C1 LLC_VICTIMS_M +CBOX1C1 LLC_VICTIMS_M +CBOX2C1 LLC_VICTIMS_M +CBOX3C1 LLC_VICTIMS_M +CBOX4C1 LLC_VICTIMS_M +CBOX5C1 LLC_VICTIMS_M +CBOX6C1 LLC_VICTIMS_M +CBOX7C1 LLC_VICTIMS_M +CBOX8C1 LLC_VICTIMS_M +CBOX9C1 LLC_VICTIMS_M +CBOX10C1 LLC_VICTIMS_M +CBOX11C1 LLC_VICTIMS_M +CBOX12C1 LLC_VICTIMS_M +CBOX13C1 LLC_VICTIMS_M +CBOX14C1 LLC_VICTIMS_M +CBOX15C1 LLC_VICTIMS_M +CBOX0C0 LLC_LOOKUP_DATA_READ +CBOX1C0 LLC_LOOKUP_DATA_READ +CBOX2C0 LLC_LOOKUP_DATA_READ +CBOX3C0 LLC_LOOKUP_DATA_READ +CBOX4C0 LLC_LOOKUP_DATA_READ +CBOX5C0 LLC_LOOKUP_DATA_READ +CBOX6C0 LLC_LOOKUP_DATA_READ +CBOX7C0 LLC_LOOKUP_DATA_READ +CBOX8C0 LLC_LOOKUP_DATA_READ +CBOX9C0 LLC_LOOKUP_DATA_READ +CBOX10C0 LLC_LOOKUP_DATA_READ +CBOX11C0 LLC_LOOKUP_DATA_READ +CBOX12C0 LLC_LOOKUP_DATA_READ +CBOX13C0 LLC_LOOKUP_DATA_READ +CBOX14C0 LLC_LOOKUP_DATA_READ +CBOX15C0 LLC_LOOKUP_DATA_READ +MBOX0C0 CAS_COUNT_RD +MBOX0C1 CAS_COUNT_WR +MBOX1C0 CAS_COUNT_RD +MBOX1C1 CAS_COUNT_WR +MBOX2C0 CAS_COUNT_RD +MBOX2C1 CAS_COUNT_WR +MBOX3C0 CAS_COUNT_RD +MBOX3C1 CAS_COUNT_WR +MBOX4C0 CAS_COUNT_RD +MBOX4C1 CAS_COUNT_WR +MBOX5C0 CAS_COUNT_RD +MBOX5C1 CAS_COUNT_WR +MBOX6C0 CAS_COUNT_RD +MBOX6C1 CAS_COUNT_WR +MBOX7C0 CAS_COUNT_RD +MBOX7C1 CAS_COUNT_WR + + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L2 to L1 load bandwidth [MBytes/s] 1.0E-06*PMC0*64.0/time +L2 to L1 load data volume [GBytes] 1.0E-09*PMC0*64.0 +L1 to L2 evict bandwidth [MBytes/s] 1.0E-06*PMC1*64.0/time +L1 to L2 evict data volume [GBytes] 1.0E-09*PMC1*64.0 +L1 to/from L2 bandwidth [MBytes/s] 1.0E-06*(PMC0+PMC1)*64.0/time +L1 to/from L2 data volume [GBytes] 1.0E-09*(PMC0+PMC1)*64.0 +L3 to L2 load bandwidth [MBytes/s] 1.0E-06*PMC2*64.0/time +L3 to L2 load data volume [GBytes] 1.0E-09*PMC2*64.0 +L2 to L3 evict bandwidth [MBytes/s] 1.0E-06*PMC3*64.0/time +L2 to L3 evict data volume [GBytes] 1.0E-09*PMC3*64.0 +L2 to/from L3 bandwidth [MBytes/s] 1.0E-06*(PMC2+PMC3)*64.0/time +L2 to/from L3 data volume [GBytes] 1.0E-09*(PMC2+PMC3)*64.0 +System to L3 bandwidth [MBytes/s] 1.0E-06*(CBOX0C0+CBOX1C0+CBOX2C0+CBOX3C0+CBOX4C0+CBOX5C0+CBOX6C0+CBOX7C0+CBOX8C0+CBOX9C0+CBOX10C0+CBOX11C0+CBOX12C0+CBOX13C0+CBOX14C0+CBOX15C0)*64.0/time +System to L3 data volume [GBytes] 1.0E-09*(CBOX0C0+CBOX1C0+CBOX2C0+CBOX3C0+CBOX4C0+CBOX5C0+CBOX6C0+CBOX7C0+CBOX8C0+CBOX9C0+CBOX10C0+CBOX11C0+CBOX12C0+CBOX13C0+CBOX14C0+CBOX15C0)*64.0 +L3 to system bandwidth [MBytes/s] 1.0E-06*(CBOX0C1+CBOX1C1+CBOX2C1+CBOX3C1+CBOX4C1+CBOX5C1+CBOX6C1+CBOX7C1+CBOX8C1+CBOX9C1+CBOX10C1+CBOX11C1+CBOX12C1+CBOX13C1+CBOX14C1+CBOX15C1)*64/time +L3 to system data volume [GBytes] 1.0E-09*(CBOX0C1+CBOX1C1+CBOX2C1+CBOX3C1+CBOX4C1+CBOX5C1+CBOX6C1+CBOX7C1+CBOX8C1+CBOX9C1+CBOX10C1+CBOX11C1+CBOX12C1+CBOX13C1+CBOX14C1+CBOX15C1)*64 +L3 to/from system bandwidth [MBytes/s] 1.0E-06*(CBOX0C0+CBOX1C0+CBOX2C0+CBOX3C0+CBOX4C0+CBOX5C0+CBOX6C0+CBOX7C0+CBOX8C0+CBOX9C0+CBOX10C0+CBOX11C0+CBOX12C0+CBOX13C0+CBOX14C0+CBOX15C0+CBOX0C1+CBOX1C1+CBOX2C1+CBOX3C1+CBOX4C1+CBOX5C1+CBOX6C1+CBOX7C1+CBOX8C1+CBOX9C1+CBOX10C1+CBOX11C1+CBOX12C1+CBOX13C1+CBOX14C1+CBOX15C1)*64.0/time +L3 to/from system data volume [GBytes] 1.0E-09*(CBOX0C0+CBOX1C0+CBOX2C0+CBOX3C0+CBOX4C0+CBOX5C0+CBOX6C0+CBOX7C0+CBOX8C0+CBOX9C0+CBOX10C0+CBOX11C0+CBOX12C0+CBOX13C0+CBOX14C0+CBOX15C0+CBOX0C1+CBOX1C1+CBOX2C1+CBOX3C1+CBOX4C1+CBOX5C1+CBOX6C1+CBOX7C1+CBOX8C1+CBOX9C1+CBOX10C1+CBOX11C1+CBOX12C1+CBOX13C1+CBOX14C1+CBOX15C1)*64.0 +Memory read bandwidth [MBytes/s] 1.0E-06*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX6C0+MBOX7C0)*64.0/time +Memory read data volume [GBytes] 1.0E-09*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX6C0+MBOX7C0)*64.0 +Memory write bandwidth [MBytes/s] 1.0E-06*(MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1+MBOX6C1+MBOX7C1)*64.0/time +Memory write data volume [GBytes] 1.0E-09*(MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1+MBOX6C1+MBOX7C1)*64.0 +Memory bandwidth [MBytes/s] 1.0E-06*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX6C0+MBOX7C0+MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1+MBOX6C1+MBOX7C1)*64.0/time +Memory data volume [GBytes] 1.0E-09*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX6C0+MBOX7C0+MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1+MBOX6C1+MBOX7C1)*64.0 + +LONG +Formulas: +L2 to L1 load bandwidth [MBytes/s] = 1.0E-06*L1D_REPLACEMENT*64/time +L2 to L1 load data volume [GBytes] = 1.0E-09*L1D_REPLACEMENT*64 +L1 to L2 evict bandwidth [MBytes/s] = 1.0E-06*L2_TRANS_L1D_WB*64/time +L1 to L2 evict data volume [GBytes] = 1.0E-09*L2_TRANS_L1D_WB*64 +L1 to/from L2 bandwidth [MBytes/s] = 1.0E-06*(L1D_REPLACEMENT+L2_TRANS_L1D_WB)*64/time +L1 to/from L2 data volume [GBytes] = 1.0E-09*(L1D_REPLACEMENT+L2_TRANS_L1D_WB)*64 +L3 to L2 load bandwidth [MBytes/s] = 1.0E-06*L2_LINES_IN_ALL*64/time +L3 to L2 load data volume [GBytes] = 1.0E-09*L2_LINES_IN_ALL*64 +L2 to L3 evict bandwidth [MBytes/s] = 1.0E-06*L2_TRANS_L2_WB*64/time +L2 to L3 evict data volume [GBytes] = 1.0E-09*L2_TRANS_L2_WB*64 +L2 to/from L3 bandwidth [MBytes/s] = 1.0E-06*(L2_LINES_IN_ALL+L2_TRANS_L2_WB)*64/time +L2 to/from L3 data volume [GBytes] = 1.0E-09*(L2_LINES_IN_ALL+L2_TRANS_L2_WB)*64 +System to L3 bandwidth [MBytes/s] = 1.0E-06*(SUM(LLC_LOOKUP_DATA_READ))*64/time +System to L3 data volume [GBytes] = 1.0E-09*(SUM(LLC_LOOKUP_DATA_READ))*64 +L3 to system bandwidth [MBytes/s] = 1.0E-06*(SUM(LLC_VICTIMS_M))*64/time +L3 to system data volume [GBytes] = 1.0E-09*(SUM(LLC_VICTIMS_M))*64 +L3 to/from system bandwidth [MBytes/s] = 1.0E-06*(SUM(LLC_LOOKUP_DATA_READ)+SUM(LLC_VICTIMS_M))*64/time +L3 to/from system data volume [GBytes] = 1.0E-09*(SUM(LLC_LOOKUP_DATA_READ)+SUM(LLC_VICTIMS_M))*64 +Memory read bandwidth [MBytes/s] = 1.0E-06*(SUM(CAS_COUNT_RD))*64.0/time +Memory read data volume [GBytes] = 1.0E-09*(SUM(CAS_COUNT_RD))*64.0 +Memory write bandwidth [MBytes/s] = 1.0E-06*(SUM(CAS_COUNT_WR))*64.0/time +Memory write data volume [GBytes] = 1.0E-09*(SUM(CAS_COUNT_WR))*64.0 +Memory bandwidth [MBytes/s] = 1.0E-06*(SUM(CAS_COUNT_RD)+SUM(CAS_COUNT_WR))*64.0/time +Memory data volume [GBytes] = 1.0E-09*(SUM(CAS_COUNT_RD)+SUM(CAS_COUNT_WR))*64.0 +- +Group to measure cache transfers between L1 and Memory. Please notice that the +L3 to/from system metrics contain any traffic to the system (memory, +Intel QPI, etc.) but don't seem to handle anything because commonly memory read +bandwidth and L3 to L2 bandwidth is higher as the memory to L3 bandwidth. + diff --git a/collectors/likwid/groups/broadwellD/CLOCK.txt b/collectors/likwid/groups/broadwellD/CLOCK.txt new file mode 100644 index 0000000..b81bee6 --- /dev/null +++ b/collectors/likwid/groups/broadwellD/CLOCK.txt @@ -0,0 +1,26 @@ +SHORT Power and Energy consumption + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PWR0 PWR_PKG_ENERGY +UBOXFIX UNCORE_CLOCK + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +Uncore Clock [MHz] 1.E-06*UBOXFIX/time +CPI FIXC1/FIXC0 +Energy [J] PWR0 +Power [W] PWR0/time + +LONG +Formulas: +Power = PWR_PKG_ENERGY / time +Uncore Clock [MHz] = 1.E-06 * UNCORE_CLOCK / time +- +Broadwell implements the new RAPL interface. This interface enables to +monitor the consumed energy on the package (socket) level. + diff --git a/collectors/likwid/groups/broadwellD/CYCLE_ACTIVITY.txt b/collectors/likwid/groups/broadwellD/CYCLE_ACTIVITY.txt new file mode 100644 index 0000000..c432a44 --- /dev/null +++ b/collectors/likwid/groups/broadwellD/CYCLE_ACTIVITY.txt @@ -0,0 +1,38 @@ +SHORT Cycle Activities + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 CYCLE_ACTIVITY_CYCLES_L2_PENDING +PMC1 CYCLE_ACTIVITY_CYCLES_LDM_PENDING +PMC2 CYCLE_ACTIVITY_CYCLES_L1D_PENDING +PMC3 CYCLE_ACTIVITY_CYCLES_NO_EXECUTE + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Cycles without execution [%] (PMC3/FIXC1)*100 +Cycles without execution due to L1D [%] (PMC2/FIXC1)*100 +Cycles without execution due to L2 [%] (PMC0/FIXC1)*100 +Cycles without execution due to memory loads [%] (PMC1/FIXC1)*100 + +LONG +Formulas: +Cycles without execution [%] = CYCLE_ACTIVITY_CYCLES_NO_EXECUTE/CPU_CLK_UNHALTED_CORE*100 +Cycles with stalls due to L1D [%] = CYCLE_ACTIVITY_CYCLES_L1D_PENDING/CPU_CLK_UNHALTED_CORE*100 +Cycles with stalls due to L2 [%] = CYCLE_ACTIVITY_CYCLES_L2_PENDING/CPU_CLK_UNHALTED_CORE*100 +Cycles without execution due to memory loads [%] = CYCLE_ACTIVITY_CYCLES_LDM_PENDING/CPU_CLK_UNHALTED_CORE*100 +-- +This performance group measures the cycles while waiting for data from the cache +and memory hierarchy. +CYCLE_ACTIVITY_CYCLES_NO_EXECUTE: Counts number of cycles nothing is executed on +any execution port. +CYCLE_ACTIVITY_CYCLES_L1D_PENDING: Cycles while L1 cache miss demand load is +outstanding. +CYCLE_ACTIVITY_CYCLES_L2_PENDING: Cycles while L2 cache miss demand load is +outstanding. +CYCLE_ACTIVITY_CYCLES_LDM_PENDING: Cycles while memory subsystem has an +outstanding load. diff --git a/collectors/likwid/groups/broadwellD/CYCLE_STALLS.txt b/collectors/likwid/groups/broadwellD/CYCLE_STALLS.txt new file mode 100644 index 0000000..795aeb9 --- /dev/null +++ b/collectors/likwid/groups/broadwellD/CYCLE_STALLS.txt @@ -0,0 +1,45 @@ +SHORT Cycle Activities (Stalls) + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 CYCLE_ACTIVITY_STALLS_L2_PENDING +PMC1 CYCLE_ACTIVITY_STALLS_LDM_PENDING +PMC2 CYCLE_ACTIVITY_STALLS_L1D_PENDING +PMC3 CYCLE_ACTIVITY_STALLS_TOTAL + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Total execution stalls PMC3 +Stalls caused by L1D misses [%] (PMC2/PMC3)*100 +Stalls caused by L2 misses [%] (PMC0/PMC3)*100 +Stalls caused by memory loads [%] (PMC1/PMC3)*100 +Execution stall rate [%] (PMC3/FIXC1)*100 +Stalls caused by L1D misses rate [%] (PMC2/FIXC1)*100 +Stalls caused by L2 misses rate [%] (PMC0/FIXC1)*100 +Stalls caused by memory loads rate [%] (PMC1/FIXC1)*100 + +LONG +Formulas: +Total execution stalls = CYCLE_ACTIVITY_STALLS_TOTAL +Stalls caused by L1D misses [%] = (CYCLE_ACTIVITY_STALLS_L1D_PENDING/CYCLE_ACTIVITY_STALLS_TOTAL)*100 +Stalls caused by L2 misses [%] = (CYCLE_ACTIVITY_STALLS_L2_PENDING/CYCLE_ACTIVITY_STALLS_TOTAL)*100 +Stalls caused by memory loads [%] = (CYCLE_ACTIVITY_STALLS_LDM_PENDING/CYCLE_ACTIVITY_STALLS_TOTAL)*100 +Execution stall rate [%] = (CYCLE_ACTIVITY_STALLS_TOTAL/CPU_CLK_UNHALTED_CORE)*100 +Stalls caused by L1D misses rate [%] = (CYCLE_ACTIVITY_STALLS_L1D_PENDING/CPU_CLK_UNHALTED_CORE)*100 +Stalls caused by L2 misses rate [%] = (CYCLE_ACTIVITY_STALLS_L2_PENDING/CPU_CLK_UNHALTED_CORE)*100 +Stalls caused by memory loads rate [%] = (CYCLE_ACTIVITY_STALLS_LDM_PENDING/CPU_CLK_UNHALTED_CORE)*100 +-- +This performance group measures the stalls caused by data traffic in the cache +hierarchy. +CYCLE_ACTIVITY_STALLS_TOTAL: Total execution stalls. +CYCLE_ACTIVITY_STALLS_L1D_PENDING: Execution stalls while L1 cache miss demand +load is outstanding. +CYCLE_ACTIVITY_STALLS_L2_PENDING: Execution stalls while L2 cache miss demand +load is outstanding. +CYCLE_ACTIVITY_STALLS_LDM_PENDING: Execution stalls while memory subsystem has +an outstanding load. diff --git a/collectors/likwid/groups/broadwellD/DATA.txt b/collectors/likwid/groups/broadwellD/DATA.txt new file mode 100644 index 0000000..6955eb7 --- /dev/null +++ b/collectors/likwid/groups/broadwellD/DATA.txt @@ -0,0 +1,22 @@ +SHORT Load to store ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 MEM_UOPS_RETIRED_LOADS_ALL +PMC1 MEM_UOPS_RETIRED_STORES_ALL + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Load to store ratio PMC0/PMC1 + +LONG +Formulas: +Load to store ratio = MEM_UOPS_RETIRED_LOADS_ALL/MEM_UOPS_RETIRED_STORES_ALL +- +This is a metric to determine your load to store ratio. + diff --git a/collectors/likwid/groups/broadwellD/DIVIDE.txt b/collectors/likwid/groups/broadwellD/DIVIDE.txt new file mode 100644 index 0000000..c7c5fb2 --- /dev/null +++ b/collectors/likwid/groups/broadwellD/DIVIDE.txt @@ -0,0 +1,24 @@ +SHORT Divide unit information + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0:EDGEDETECT ARITH_FPU_DIV_ACTIVE +PMC1 ARITH_FPU_DIV_ACTIVE + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Number of divide ops PMC0:EDGEDETECT +Avg. divide unit usage duration PMC1/PMC0:EDGEDETECT + +LONG +Formulas: +Number of divide ops = ARITH_FPU_DIV_ACTIVE:EDGEDETECT +Avg. divide unit usage duration = ARITH_FPU_DIV_ACTIVE/ARITH_FPU_DIV_ACTIVE:EDGEDETECT +- +This performance group measures the average latency of divide operations diff --git a/collectors/likwid/groups/broadwellD/ENERGY.txt b/collectors/likwid/groups/broadwellD/ENERGY.txt new file mode 100644 index 0000000..09eaeb1 --- /dev/null +++ b/collectors/likwid/groups/broadwellD/ENERGY.txt @@ -0,0 +1,39 @@ +SHORT Power and Energy consumption + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +TMP0 TEMP_CORE +PWR0 PWR_PKG_ENERGY +PWR1 PWR_PP0_ENERGY +PWR2 PWR_PP1_ENERGY +PWR3 PWR_DRAM_ENERGY + + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Temperature [C] TMP0 +Energy [J] PWR0 +Power [W] PWR0/time +Energy PP0 [J] PWR1 +Power PP0 [W] PWR1/time +Energy PP1 [J] PWR2 +Power PP1 [W] PWR2/time +Energy DRAM [J] PWR3 +Power DRAM [W] PWR3/time + +LONG +Formulas: +Power = PWR_PKG_ENERGY / time +Power PP0 = PWR_PP0_ENERGY / time +Power PP1 = PWR_PP1_ENERGY / time +Power DRAM = PWR_DRAM_ENERGY / time +- +Broadwell implements the new RAPL interface. This interface enables to +monitor the consumed energy on the package (socket) and DRAM level. + diff --git a/collectors/likwid/groups/broadwellD/FALSE_SHARE.txt b/collectors/likwid/groups/broadwellD/FALSE_SHARE.txt new file mode 100644 index 0000000..68107bf --- /dev/null +++ b/collectors/likwid/groups/broadwellD/FALSE_SHARE.txt @@ -0,0 +1,25 @@ +SHORT False sharing + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 MEM_LOAD_UOPS_L3_HIT_RETIRED_XSNP_HITM +PMC2 MEM_UOPS_RETIRED_LOADS_ALL + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Local LLC false sharing [MByte] 1.E-06*PMC0*64 +Local LLC false sharing rate PMC0/PMC2 + +LONG +Formulas: +Local LLC false sharing [MByte] = 1.E-06*MEM_LOAD_UOPS_L3_HIT_RETIRED_XSNP_HITM*64 +Local LLC false sharing rate = MEM_LOAD_UOPS_L3_HIT_RETIRED_XSNP_HITM/MEM_UOPS_RETIRED_LOADS_ALL +- +False-sharing of cache lines can dramatically reduce the performance of an +application. This performance group measures the L3 traffic induced by false-sharing. +The false-sharing rate uses all memory loads as reference. diff --git a/collectors/likwid/groups/broadwellD/FLOPS_AVX.txt b/collectors/likwid/groups/broadwellD/FLOPS_AVX.txt new file mode 100644 index 0000000..7854608 --- /dev/null +++ b/collectors/likwid/groups/broadwellD/FLOPS_AVX.txt @@ -0,0 +1,24 @@ +SHORT Packed AVX MFLOP/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE +PMC1 FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Packed SP [MFLOP/s] 1.0E-06*(PMC0*8.0)/time +Packed DP [MFLOP/s] 1.0E-06*(PMC1*4.0)/time + +LONG +Formulas: +Packed SP [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE*8)/runtime +Packed DP [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE*4)/runtime +- +FLOP rates of 256 bit packed floating-point instructions + diff --git a/collectors/likwid/groups/broadwellD/FLOPS_DP.txt b/collectors/likwid/groups/broadwellD/FLOPS_DP.txt new file mode 100644 index 0000000..348ec76 --- /dev/null +++ b/collectors/likwid/groups/broadwellD/FLOPS_DP.txt @@ -0,0 +1,31 @@ +SHORT Double Precision MFLOP/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 FP_ARITH_INST_RETIRED_128B_PACKED_DOUBLE +PMC1 FP_ARITH_INST_RETIRED_SCALAR_DOUBLE +PMC2 FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +DP [MFLOP/s] 1.0E-06*(PMC0*2.0+PMC1+PMC2*4.0)/time +AVX DP [MFLOP/s] 1.0E-06*(PMC2*4.0)/time +Packed [MUOPS/s] 1.0E-06*(PMC0+PMC2)/time +Scalar [MUOPS/s] 1.0E-06*PMC1/time +Vectorization ratio 100*(PMC0+PMC2)/(PMC0+PMC1+PMC2) + +LONG +Formulas: +DP [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_128B_PACKED_DOUBLE*2+FP_ARITH_INST_RETIRED_SCALAR_DOUBLE+FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE*4)/runtime +AVX DP [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE*4)/runtime +Packed [MUOPS/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_128B_PACKED_DOUBLE+FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE)/runtime +Scalar [MUOPS/s] = 1.0E-06*FP_ARITH_INST_RETIRED_SCALAR_DOUBLE/runtime +Vectorization ratio = 100*(FP_ARITH_INST_RETIRED_128B_PACKED_DOUBLE+FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE)/(FP_ARITH_INST_RETIRED_SCALAR_DOUBLE+FP_ARITH_INST_RETIRED_128B_PACKED_DOUBLE+FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE) +- +AVX/SSE scalar and packed double precision FLOP rates. + diff --git a/collectors/likwid/groups/broadwellD/FLOPS_SP.txt b/collectors/likwid/groups/broadwellD/FLOPS_SP.txt new file mode 100644 index 0000000..1d7fd7c --- /dev/null +++ b/collectors/likwid/groups/broadwellD/FLOPS_SP.txt @@ -0,0 +1,31 @@ +SHORT Single Precision MFLOP/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 FP_ARITH_INST_RETIRED_128B_PACKED_SINGLE +PMC1 FP_ARITH_INST_RETIRED_SCALAR_SINGLE +PMC2 FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +SP [MFLOP/s] 1.0E-06*(PMC0*4.0+PMC1+PMC2*8.0)/time +AVX SP [MFLOP/s] 1.0E-06*(PMC2*8.0)/time +Packed [MUOPS/s] 1.0E-06*(PMC0+PMC2)/time +Scalar [MUOPS/s] 1.0E-06*PMC1/time +Vectorization ratio 100*(PMC0+PMC2)/(PMC0+PMC1+PMC2) + +LONG +Formulas: +SP [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_128B_PACKED_SINGLE*4+FP_ARITH_INST_RETIRED_SCALAR_SINGLE+FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE*8)/runtime +AVX SP [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE*8)/runtime +Packed [MUOPS/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_128B_PACKED_SINGLE+FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE)/runtime +Scalar [MUOPS/s] = 1.0E-06*FP_ARITH_INST_RETIRED_SCALAR_SINGLE/runtime +Vectorization ratio [%] = 100*(FP_ARITH_INST_RETIRED_128B_PACKED_SINGLE+FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE)/(FP_ARITH_INST_RETIRED_SCALAR_SINGLE+FP_ARITH_INST_RETIRED_128B_PACKED_SINGLE+FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE) +- +AVX/SSE scalar and packed single precision FLOP rates. + diff --git a/collectors/likwid/groups/broadwellD/HA.txt b/collectors/likwid/groups/broadwellD/HA.txt new file mode 100644 index 0000000..1e5a700 --- /dev/null +++ b/collectors/likwid/groups/broadwellD/HA.txt @@ -0,0 +1,40 @@ +SHORT Main memory bandwidth in MBytes/s seen from Home agent + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +BBOX0C0 IMC_READS_NORMAL +BBOX0C1 BYPASS_IMC_TAKEN +BBOX0C2 IMC_WRITES_ALL +BBOX1C0 IMC_READS_NORMAL +BBOX1C1 BYPASS_IMC_TAKEN +BBOX1C2 IMC_WRITES_ALL + + + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Memory read bandwidth [MBytes/s] 1.0E-06*(BBOX0C0+BBOX1C0+BBOX0C1+BBOX1C1)*64.0/time +Memory read data volume [GBytes] 1.0E-09*(BBOX0C0+BBOX1C0+BBOX0C1+BBOX1C1)*64.0 +Memory write bandwidth [MBytes/s] 1.0E-06*(BBOX0C2+BBOX1C2)*64.0/time +Memory write data volume [GBytes] 1.0E-09*(BBOX0C2+BBOX1C2)*64.0 +Memory bandwidth [MBytes/s] 1.0E-06*(BBOX0C0+BBOX1C0+BBOX0C1+BBOX1C1+BBOX0C2+BBOX1C2)*64.0/time +Memory data volume [GBytes] 1.0E-09*(BBOX0C0+BBOX1C0+BBOX0C1+BBOX1C1+BBOX0C2+BBOX1C2)*64.0 + +LONG +Formulas: +Memory read bandwidth [MBytes/s] = 1.0E-06*(SUM(IMC_READS_NORMAL)+SUM(BYPASS_IMC_TAKEN))*64.0/time +Memory read data volume [GBytes] = 1.0E-09*(SUM(IMC_READS_NORMAL)+SUM(BYPASS_IMC_TAKEN))*64.0 +Memory write bandwidth [MBytes/s] = 1.0E-06*(SUM(IMC_WRITES_ALL))*64.0/time +Memory write data volume [GBytes] = 1.0E-09*(SUM(IMC_WRITES_ALL))*64.0 +Memory bandwidth [MBytes/s] = 1.0E-06*(SUM(IMC_READS_NORMAL) + SUM(BYPASS_IMC_TAKEN) + SUM(IMC_WRITES_ALL))*64.0/time +Memory data volume [GBytes] = 1.0E-09*(SUM(IMC_READS_NORMAL) + SUM(BYPASS_IMC_TAKEN) + SUM(IMC_WRITES_ALL))*64.0 +- +This group derives the same metrics as the MEM group but use the events of the +Home Agent, a central unit that is responsible for the protocol side of memory +interactions. diff --git a/collectors/likwid/groups/broadwellD/ICACHE.txt b/collectors/likwid/groups/broadwellD/ICACHE.txt new file mode 100644 index 0000000..5f11ad6 --- /dev/null +++ b/collectors/likwid/groups/broadwellD/ICACHE.txt @@ -0,0 +1,25 @@ +SHORT Instruction cache miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 ICACHE_ACCESSES +PMC1 ICACHE_MISSES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L1I request rate PMC0/FIXC0 +L1I miss rate PMC1/FIXC0 +L1I miss ratio PMC1/PMC0 + +LONG +Formulas: +L1I request rate = ICACHE_ACCESSES / INSTR_RETIRED_ANY +L1I miss rate = ICACHE_MISSES / INSTR_RETIRED_ANY +L1I miss ratio = ICACHE_MISSES / ICACHE_ACCESSES +- +This group measures some L1 instruction cache metrics. diff --git a/collectors/likwid/groups/broadwellD/L2.txt b/collectors/likwid/groups/broadwellD/L2.txt new file mode 100644 index 0000000..60c7f79 --- /dev/null +++ b/collectors/likwid/groups/broadwellD/L2.txt @@ -0,0 +1,37 @@ +SHORT L2 cache bandwidth in MBytes/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 L1D_REPLACEMENT +PMC1 L2_TRANS_L1D_WB +PMC2 ICACHE_MISSES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L2D load bandwidth [MBytes/s] 1.0E-06*PMC0*64.0/time +L2D load data volume [GBytes] 1.0E-09*PMC0*64.0 +L2D evict bandwidth [MBytes/s] 1.0E-06*PMC1*64.0/time +L2D evict data volume [GBytes] 1.0E-09*PMC1*64.0 +L2 bandwidth [MBytes/s] 1.0E-06*(PMC0+PMC1+PMC2)*64.0/time +L2 data volume [GBytes] 1.0E-09*(PMC0+PMC1+PMC2)*64.0 + +LONG +Formulas: +L2D load bandwidth [MBytes/s] = 1.0E-06*L1D_REPLACEMENT*64.0/time +L2D load data volume [GBytes] = 1.0E-09*L1D_REPLACEMENT*64.0 +L2D evict bandwidth [MBytes/s] = 1.0E-06*L2_TRANS_L1D_WB*64.0/time +L2D evict data volume [GBytes] = 1.0E-09*L2_TRANS_L1D_WB*64.0 +L2 bandwidth [MBytes/s] = 1.0E-06*(L1D_REPLACEMENT+L2_TRANS_L1D_WB+ICACHE_MISSES)*64.0/time +L2 data volume [GBytes] = 1.0E-09*(L1D_REPLACEMENT+L2_TRANS_L1D_WB+ICACHE_MISSES)*64.0 +- +Profiling group to measure L2 cache bandwidth. The bandwidth is computed by the +number of cache line loaded from the L2 to the L2 data cache and the writebacks from +the L2 data cache to the L2 cache. The group also outputs total data volume transferred between +L2 and L1. Note that this bandwidth also includes data transfers due to a write +allocate load on a store miss in L1 and cache lines transferred it the instruction +cache. diff --git a/collectors/likwid/groups/broadwellD/L2CACHE.txt b/collectors/likwid/groups/broadwellD/L2CACHE.txt new file mode 100644 index 0000000..9b5dd4b --- /dev/null +++ b/collectors/likwid/groups/broadwellD/L2CACHE.txt @@ -0,0 +1,34 @@ +SHORT L2 cache miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 L2_TRANS_ALL_REQUESTS +PMC1 L2_RQSTS_MISS + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L2 request rate PMC0/FIXC0 +L2 miss rate PMC1/FIXC0 +L2 miss ratio PMC1/PMC0 + +LONG +Formulas: +L2 request rate = L2_TRANS_ALL_REQUESTS/INSTR_RETIRED_ANY +L2 miss rate = L2_RQSTS_MISS/INSTR_RETIRED_ANY +L2 miss ratio = L2_RQSTS_MISS/L2_TRANS_ALL_REQUESTS +- +This group measures the locality of your data accesses with regard to the +L2 cache. L2 request rate tells you how data intensive your code is +or how many data accesses you have on average per instruction. +The L2 miss rate gives a measure how often it was necessary to get +cache lines from memory. And finally L2 miss ratio tells you how many of your +memory references required a cache line to be loaded from a higher level. +While the# data cache miss rate might be given by your algorithm you should +try to get data cache miss ratio as low as possible by increasing your cache reuse. + + diff --git a/collectors/likwid/groups/broadwellD/L3.txt b/collectors/likwid/groups/broadwellD/L3.txt new file mode 100644 index 0000000..98d1d9e --- /dev/null +++ b/collectors/likwid/groups/broadwellD/L3.txt @@ -0,0 +1,36 @@ +SHORT L3 cache bandwidth in MBytes/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 L2_LINES_IN_ALL +PMC1 L2_TRANS_L2_WB + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L3 load bandwidth [MBytes/s] 1.0E-06*PMC0*64.0/time +L3 load data volume [GBytes] 1.0E-09*PMC0*64.0 +L3 evict bandwidth [MBytes/s] 1.0E-06*PMC1*64.0/time +L3 evict data volume [GBytes] 1.0E-09*PMC1*64.0 +L3 bandwidth [MBytes/s] 1.0E-06*(PMC0+PMC1)*64.0/time +L3 data volume [GBytes] 1.0E-09*(PMC0+PMC1)*64.0 + +LONG +Formulas: +L3 load bandwidth [MBytes/s] = 1.0E-06*L2_LINES_IN_ALL*64.0/time +L3 load data volume [GBytes] = 1.0E-09*L2_LINES_IN_ALL*64.0 +L3 evict bandwidth [MBytes/s] = 1.0E-06*L2_TRANS_L2_WB*64.0/time +L3 evict data volume [GBytes] = 1.0E-09*L2_TRANS_L2_WB*64.0 +L3 bandwidth [MBytes/s] = 1.0E-06*(L2_LINES_IN_ALL+L2_TRANS_L2_WB)*64/time +L3 data volume [GBytes] = 1.0E-09*(L2_LINES_IN_ALL+L2_TRANS_L2_WB)*64 +- +Profiling group to measure L3 cache bandwidth. The bandwidth is computed by the +number of cache line allocated in the L2 and the number of modified cache lines +evicted from the L2. This group also output data volume transferred between the +L3 and measured cores L2 caches. Note that this bandwidth also includes data +transfers due to a write allocate load on a store miss in L2. + diff --git a/collectors/likwid/groups/broadwellD/L3CACHE.txt b/collectors/likwid/groups/broadwellD/L3CACHE.txt new file mode 100644 index 0000000..f863daa --- /dev/null +++ b/collectors/likwid/groups/broadwellD/L3CACHE.txt @@ -0,0 +1,35 @@ +SHORT L3 cache miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 MEM_LOAD_UOPS_RETIRED_L3_ALL +PMC1 MEM_LOAD_UOPS_RETIRED_L3_MISS +PMC2 UOPS_RETIRED_ALL + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L3 request rate PMC0/PMC2 +L3 miss rate PMC1/PMC2 +L3 miss ratio PMC1/PMC0 + +LONG +Formulas: +L3 request rate = MEM_LOAD_UOPS_RETIRED_L3_ALL/UOPS_RETIRED_ALL +L3 miss rate = MEM_LOAD_UOPS_RETIRED_L3_MISS/UOPS_RETIRED_ALL +L3 miss ratio = MEM_LOAD_UOPS_RETIRED_L3_MISS/MEM_LOAD_UOPS_RETIRED_L3_ALL +- +This group measures the locality of your data accesses with regard to the +L3 cache. L3 request rate tells you how data intensive your code is +or how many data accesses you have on average per instruction. +The L3 miss rate gives a measure how often it was necessary to get +cache lines from memory. And finally L3 miss ratio tells you how many of your +memory references required a cache line to be loaded from a higher level. +While the# data cache miss rate might be given by your algorithm you should +try to get data cache miss ratio as low as possible by increasing your cache reuse. + + diff --git a/collectors/likwid/groups/broadwellD/MEM.txt b/collectors/likwid/groups/broadwellD/MEM.txt new file mode 100644 index 0000000..2a17a2c --- /dev/null +++ b/collectors/likwid/groups/broadwellD/MEM.txt @@ -0,0 +1,52 @@ +SHORT Main memory bandwidth in MBytes/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +MBOX0C0 CAS_COUNT_RD +MBOX0C1 CAS_COUNT_WR +MBOX1C0 CAS_COUNT_RD +MBOX1C1 CAS_COUNT_WR +MBOX2C0 CAS_COUNT_RD +MBOX2C1 CAS_COUNT_WR +MBOX3C0 CAS_COUNT_RD +MBOX3C1 CAS_COUNT_WR +MBOX4C0 CAS_COUNT_RD +MBOX4C1 CAS_COUNT_WR +MBOX5C0 CAS_COUNT_RD +MBOX5C1 CAS_COUNT_WR +MBOX6C0 CAS_COUNT_RD +MBOX6C1 CAS_COUNT_WR +MBOX7C0 CAS_COUNT_RD +MBOX7C1 CAS_COUNT_WR + + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Memory read bandwidth [MBytes/s] 1.0E-06*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX6C0+MBOX7C0)*64.0/time +Memory read data volume [GBytes] 1.0E-09*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX6C0+MBOX7C0)*64.0 +Memory write bandwidth [MBytes/s] 1.0E-06*(MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1+MBOX6C1+MBOX7C1)*64.0/time +Memory write data volume [GBytes] 1.0E-09*(MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1+MBOX6C1+MBOX7C1)*64.0 +Memory bandwidth [MBytes/s] 1.0E-06*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX6C0+MBOX7C0+MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1+MBOX6C1+MBOX7C1)*64.0/time +Memory data volume [GBytes] 1.0E-09*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX6C0+MBOX7C0+MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1+MBOX6C1+MBOX7C1)*64.0 + +LONG +Formulas: +Memory read bandwidth [MBytes/s] = 1.0E-06*(SUM(MBOXxC0))*64.0/runtime +Memory read data volume [GBytes] = 1.0E-09*(SUM(MBOXxC0))*64.0 +Memory write bandwidth [MBytes/s] = 1.0E-06*(SUM(MBOXxC1))*64.0/runtime +Memory write data volume [GBytes] = 1.0E-09*(SUM(MBOXxC1))*64.0 +Memory bandwidth [MBytes/s] = 1.0E-06*(SUM(MBOXxC0)+SUM(MBOXxC1))*64.0/runtime +Memory data volume [GBytes] = 1.0E-09*(SUM(MBOXxC0)+SUM(MBOXxC1))*64.0 +- +Profiling group to measure memory bandwidth drawn by all cores of a socket. +Since this group is based on Uncore events it is only possible to measure on a +per socket base. Some of the counters may not be available on your system. +Also outputs total data volume transferred from main memory. +The same metrics are provided by the HA group. + diff --git a/collectors/likwid/groups/broadwellD/MEM_DP.txt b/collectors/likwid/groups/broadwellD/MEM_DP.txt new file mode 100644 index 0000000..71ce2ae --- /dev/null +++ b/collectors/likwid/groups/broadwellD/MEM_DP.txt @@ -0,0 +1,73 @@ +SHORT Overview of arithmetic and main memory performance + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PWR0 PWR_PKG_ENERGY +PWR3 PWR_DRAM_ENERGY +PMC0 FP_ARITH_INST_RETIRED_128B_PACKED_DOUBLE +PMC1 FP_ARITH_INST_RETIRED_SCALAR_DOUBLE +PMC2 FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE +MBOX0C0 CAS_COUNT_RD +MBOX0C1 CAS_COUNT_WR +MBOX1C0 CAS_COUNT_RD +MBOX1C1 CAS_COUNT_WR +MBOX2C0 CAS_COUNT_RD +MBOX2C1 CAS_COUNT_WR +MBOX3C0 CAS_COUNT_RD +MBOX3C1 CAS_COUNT_WR +MBOX4C0 CAS_COUNT_RD +MBOX4C1 CAS_COUNT_WR +MBOX5C0 CAS_COUNT_RD +MBOX5C1 CAS_COUNT_WR +MBOX6C0 CAS_COUNT_RD +MBOX6C1 CAS_COUNT_WR +MBOX7C0 CAS_COUNT_RD +MBOX7C1 CAS_COUNT_WR + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Energy [J] PWR0 +Power [W] PWR0/time +Energy DRAM [J] PWR3 +Power DRAM [W] PWR3/time +MFLOP/s 1.0E-06*(PMC0*2.0+PMC1+PMC2*4.0)/time +AVX [MFLOP/s] 1.0E-06*(PMC2*4.0)/time +Packed [MUOPS/s] 1.0E-06*(PMC0+PMC2)/time +Scalar [MUOPS/s] 1.0E-06*PMC1/time +Memory read bandwidth [MBytes/s] 1.0E-06*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX6C0+MBOX7C0)*64.0/time +Memory read data volume [GBytes] 1.0E-09*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX6C0+MBOX7C0)*64.0 +Memory write bandwidth [MBytes/s] 1.0E-06*(MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1+MBOX6C1+MBOX7C1)*64.0/time +Memory write data volume [GBytes] 1.0E-09*(MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1+MBOX6C1+MBOX7C1)*64.0 +Memory bandwidth [MBytes/s] 1.0E-06*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX6C0+MBOX7C0+MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1+MBOX6C1+MBOX7C1)*64.0/time +Memory data volume [GBytes] 1.0E-09*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX6C0+MBOX7C0+MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1+MBOX6C1+MBOX7C1)*64.0 +Operational intensity (PMC0*2.0+PMC1+PMC2*4.0)/((MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX6C0+MBOX7C0+MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1+MBOX6C1+MBOX7C1)*64.0) + +LONG +Formulas: +Power [W] = PWR_PKG_ENERGY/runtime +Power DRAM [W] = PWR_DRAM_ENERGY/runtime +MFLOP/s = 1.0E-06*(FP_ARITH_INST_RETIRED_128B_PACKED_DOUBLE*2+FP_ARITH_INST_RETIRED_SCALAR_DOUBLE+FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE*4)/runtime +AVX [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE*4)/runtime +Packed [MUOPS/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_128B_PACKED_DOUBLE+FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE)/runtime +Scalar [MUOPS/s] = 1.0E-06*FP_ARITH_INST_RETIRED_SCALAR_DOUBLE/runtime +Memory read bandwidth [MBytes/s] = 1.0E-06*(SUM(MBOXxC0))*64.0/runtime +Memory read data volume [GBytes] = 1.0E-09*(SUM(MBOXxC0))*64.0 +Memory write bandwidth [MBytes/s] = 1.0E-06*(SUM(MBOXxC1))*64.0/runtime +Memory write data volume [GBytes] = 1.0E-09*(SUM(MBOXxC1))*64.0 +Memory bandwidth [MBytes/s] = 1.0E-06*(SUM(MBOXxC0)+SUM(MBOXxC1))*64.0/runtime +Memory data volume [GBytes] = 1.0E-09*(SUM(MBOXxC0)+SUM(MBOXxC1))*64.0 +Operational intensity = (FP_ARITH_INST_RETIRED_128B_PACKED_DOUBLE*2+FP_ARITH_INST_RETIRED_SCALAR_DOUBLE+FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE*4)/((SUM(MBOXxC0)+SUM(MBOXxC1))*64.0) +-- +Profiling group to measure memory bandwidth drawn by all cores of a socket. +Since this group is based on Uncore events it is only possible to measure on +a per socket base. Also outputs total data volume transferred from main memory. +SSE scalar and packed double precision FLOP rates. Also reports on packed AVX +32b instructions. +The operational intensity is calculated using the FP values of the cores and the +memory data volume of the whole socket. The actual operational intensity for +multiple CPUs can be found in the statistics table in the Sum column. diff --git a/collectors/likwid/groups/broadwellD/MEM_SP.txt b/collectors/likwid/groups/broadwellD/MEM_SP.txt new file mode 100644 index 0000000..6d67ea7 --- /dev/null +++ b/collectors/likwid/groups/broadwellD/MEM_SP.txt @@ -0,0 +1,73 @@ +SHORT Overview of arithmetic and main memory performance + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PWR0 PWR_PKG_ENERGY +PWR3 PWR_DRAM_ENERGY +PMC0 FP_ARITH_INST_RETIRED_128B_PACKED_SINGLE +PMC1 FP_ARITH_INST_RETIRED_SCALAR_SINGLE +PMC2 FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE +MBOX0C0 CAS_COUNT_RD +MBOX0C1 CAS_COUNT_WR +MBOX1C0 CAS_COUNT_RD +MBOX1C1 CAS_COUNT_WR +MBOX2C0 CAS_COUNT_RD +MBOX2C1 CAS_COUNT_WR +MBOX3C0 CAS_COUNT_RD +MBOX3C1 CAS_COUNT_WR +MBOX4C0 CAS_COUNT_RD +MBOX4C1 CAS_COUNT_WR +MBOX5C0 CAS_COUNT_RD +MBOX5C1 CAS_COUNT_WR +MBOX6C0 CAS_COUNT_RD +MBOX6C1 CAS_COUNT_WR +MBOX7C0 CAS_COUNT_RD +MBOX7C1 CAS_COUNT_WR + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Energy [J] PWR0 +Power [W] PWR0/time +Energy DRAM [J] PWR3 +Power DRAM [W] PWR3/time +MFLOP/s 1.0E-06*(PMC0*4.0+PMC1+PMC2*8.0)/time +AVX [MFLOP/s] 1.0E-06*(PMC2*8.0)/time +Packed [MUOPS/s] 1.0E-06*(PMC0+PMC2)/time +Scalar [MUOPS/s] 1.0E-06*PMC1/time +Memory read bandwidth [MBytes/s] 1.0E-06*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX6C0+MBOX7C0)*64.0/time +Memory read data volume [GBytes] 1.0E-09*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX6C0+MBOX7C0)*64.0 +Memory write bandwidth [MBytes/s] 1.0E-06*(MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1+MBOX6C1+MBOX7C1)*64.0/time +Memory write data volume [GBytes] 1.0E-09*(MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1+MBOX6C1+MBOX7C1)*64.0 +Memory bandwidth [MBytes/s] 1.0E-06*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX6C0+MBOX7C0+MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1+MBOX6C1+MBOX7C1)*64.0/time +Memory data volume [GBytes] 1.0E-09*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX6C0+MBOX7C0+MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1+MBOX6C1+MBOX7C1)*64.0 +Operational intensity (PMC0*4.0+PMC1+PMC2*8.0)/((MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX6C0+MBOX7C0+MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1+MBOX6C1+MBOX7C1)*64.0) + +LONG +Formulas: +Power [W] = PWR_PKG_ENERGY/runtime +Power DRAM [W] = PWR_DRAM_ENERGY/runtime +MFLOP/s = 1.0E-06*(FP_ARITH_INST_RETIRED_128B_PACKED_SINGLE*4+FP_ARITH_INST_RETIRED_SCALAR_SINGLE+FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE*8)/runtime +AVX [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE*8)/runtime +Packed [MUOPS/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_128B_PACKED_SINGLE+FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE)/runtime +Scalar [MUOPS/s] = 1.0E-06*FP_ARITH_INST_RETIRED_SCALAR_SINGLE/runtime +Memory read bandwidth [MBytes/s] = 1.0E-06*(SUM(MBOXxC0))*64.0/runtime +Memory read data volume [GBytes] = 1.0E-09*(SUM(MBOXxC0))*64.0 +Memory write bandwidth [MBytes/s] = 1.0E-06*(SUM(MBOXxC1))*64.0/runtime +Memory write data volume [GBytes] = 1.0E-09*(SUM(MBOXxC1))*64.0 +Memory bandwidth [MBytes/s] = 1.0E-06*(SUM(MBOXxC0)+SUM(MBOXxC1))*64.0/runtime +Memory data volume [GBytes] = 1.0E-09*(SUM(MBOXxC0)+SUM(MBOXxC1))*64.0 +Operational intensity = (FP_ARITH_INST_RETIRED_128B_PACKED_SINGLE*4+FP_ARITH_INST_RETIRED_SCALAR_SINGLE+FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE*8)/((SUM(MBOXxC0)+SUM(MBOXxC1))*64.0) +-- +Profiling group to measure memory bandwidth drawn by all cores of a socket. +Since this group is based on Uncore events it is only possible to measure on +a per socket base. Also outputs total data volume transferred from main memory. +SSE scalar and packed single precision FLOP rates. Also reports on packed AVX +32b instructions. +The operational intensity is calculated using the FP values of the cores and the +memory data volume of the whole socket. The actual operational intensity for +multiple CPUs can be found in the statistics table in the Sum column. diff --git a/collectors/likwid/groups/broadwellD/PORT_USAGE.txt b/collectors/likwid/groups/broadwellD/PORT_USAGE.txt new file mode 100644 index 0000000..298df1d --- /dev/null +++ b/collectors/likwid/groups/broadwellD/PORT_USAGE.txt @@ -0,0 +1,50 @@ +SHORT Execution port utilization + +REQUIRE_NOHT + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 UOPS_EXECUTED_PORT_PORT_0 +PMC1 UOPS_EXECUTED_PORT_PORT_1 +PMC2 UOPS_EXECUTED_PORT_PORT_2 +PMC3 UOPS_EXECUTED_PORT_PORT_3 +PMC4 UOPS_EXECUTED_PORT_PORT_4 +PMC5 UOPS_EXECUTED_PORT_PORT_5 +PMC6 UOPS_EXECUTED_PORT_PORT_6 +PMC7 UOPS_EXECUTED_PORT_PORT_7 + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Port0 usage ratio PMC0/(PMC0+PMC1+PMC2+PMC3+PMC4+PMC5+PMC6+PMC7) +Port1 usage ratio PMC1/(PMC0+PMC1+PMC2+PMC3+PMC4+PMC5+PMC6+PMC7) +Port2 usage ratio PMC2/(PMC0+PMC1+PMC2+PMC3+PMC4+PMC5+PMC6+PMC7) +Port3 usage ratio PMC3/(PMC0+PMC1+PMC2+PMC3+PMC4+PMC5+PMC6+PMC7) +Port4 usage ratio PMC4/(PMC0+PMC1+PMC2+PMC3+PMC4+PMC5+PMC6+PMC7) +Port5 usage ratio PMC5/(PMC0+PMC1+PMC2+PMC3+PMC4+PMC5+PMC6+PMC7) +Port6 usage ratio PMC6/(PMC0+PMC1+PMC2+PMC3+PMC4+PMC5+PMC6+PMC7) +Port7 usage ratio PMC7/(PMC0+PMC1+PMC2+PMC3+PMC4+PMC5+PMC6+PMC7) + +LONG +Formulas: +Port0 usage ratio = UOPS_EXECUTED_PORT_PORT_0/SUM(UOPS_EXECUTED_PORT_PORT_*) +Port1 usage ratio = UOPS_EXECUTED_PORT_PORT_1/SUM(UOPS_EXECUTED_PORT_PORT_*) +Port2 usage ratio = UOPS_EXECUTED_PORT_PORT_2/SUM(UOPS_EXECUTED_PORT_PORT_*) +Port3 usage ratio = UOPS_EXECUTED_PORT_PORT_3/SUM(UOPS_EXECUTED_PORT_PORT_*) +Port4 usage ratio = UOPS_EXECUTED_PORT_PORT_4/SUM(UOPS_EXECUTED_PORT_PORT_*) +Port5 usage ratio = UOPS_EXECUTED_PORT_PORT_5/SUM(UOPS_EXECUTED_PORT_PORT_*) +Port6 usage ratio = UOPS_EXECUTED_PORT_PORT_6/SUM(UOPS_EXECUTED_PORT_PORT_*) +Port7 usage ratio = UOPS_EXECUTED_PORT_PORT_7/SUM(UOPS_EXECUTED_PORT_PORT_*) +- +This group measures the execution port utilization in a CPU core. The group can +only be measured when HyperThreading is disabled because only then each CPU core +can program eight counters. +Please be aware that the counters PMC4-7 are broken on Intel Broadwell. They +don't increment if either user- or kernel-level filtering is applied. User-level +filtering is default in LIKWID, hence kernel-level filtering is added +automatically for PMC4-7. The returned counts can be much higher. diff --git a/collectors/likwid/groups/broadwellD/RECOVERY.txt b/collectors/likwid/groups/broadwellD/RECOVERY.txt new file mode 100644 index 0000000..7928ee4 --- /dev/null +++ b/collectors/likwid/groups/broadwellD/RECOVERY.txt @@ -0,0 +1,22 @@ +SHORT Recovery duration + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 INT_MISC_RECOVERY_CYCLES +PMC1 INT_MISC_RECOVERY_COUNT + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Avg. recovery duration PMC0/PMC1 + +LONG +Formulas: +Avg. recovery duration = INT_MISC_RECOVERY_CYCLES/INT_MISC_RECOVERY_COUNT +- +This group measures the duration of recoveries after SSE exception, memory +disambiguation, etc... diff --git a/collectors/likwid/groups/broadwellD/TLB_DATA.txt b/collectors/likwid/groups/broadwellD/TLB_DATA.txt new file mode 100644 index 0000000..8d94e05 --- /dev/null +++ b/collectors/likwid/groups/broadwellD/TLB_DATA.txt @@ -0,0 +1,35 @@ +SHORT L2 data TLB miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 DTLB_LOAD_MISSES_CAUSES_A_WALK +PMC1 DTLB_STORE_MISSES_CAUSES_A_WALK +PMC2 DTLB_LOAD_MISSES_WALK_DURATION +PMC3 DTLB_STORE_MISSES_WALK_DURATION + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L1 DTLB load misses PMC0 +L1 DTLB load miss rate PMC0/FIXC0 +L1 DTLB load miss duration [Cyc] PMC2/PMC0 +L1 DTLB store misses PMC1 +L1 DTLB store miss rate PMC1/FIXC0 +L1 DTLB store miss duration [Cyc] PMC3/PMC1 + +LONG +Formulas: +L1 DTLB load misses = DTLB_LOAD_MISSES_CAUSES_A_WALK +L1 DTLB load miss rate = DTLB_LOAD_MISSES_CAUSES_A_WALK / INSTR_RETIRED_ANY +L1 DTLB load miss duration [Cyc] = DTLB_LOAD_MISSES_WALK_DURATION / DTLB_LOAD_MISSES_CAUSES_A_WALK +L1 DTLB store misses = DTLB_STORE_MISSES_CAUSES_A_WALK +L1 DTLB store miss rate = DTLB_STORE_MISSES_CAUSES_A_WALK / INSTR_RETIRED_ANY +L1 DTLB store miss duration [Cyc] = DTLB_STORE_MISSES_WALK_DURATION / DTLB_STORE_MISSES_CAUSES_A_WALK +- +The DTLB load and store miss rates gives a measure how often a TLB miss occurred +per instruction. The duration measures the time in cycles how long a walk did take. + diff --git a/collectors/likwid/groups/broadwellD/TLB_INSTR.txt b/collectors/likwid/groups/broadwellD/TLB_INSTR.txt new file mode 100644 index 0000000..235d977 --- /dev/null +++ b/collectors/likwid/groups/broadwellD/TLB_INSTR.txt @@ -0,0 +1,28 @@ +SHORT L1 Instruction TLB miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 ITLB_MISSES_CAUSES_A_WALK +PMC1 ITLB_MISSES_WALK_DURATION + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L1 ITLB misses PMC0 +L1 ITLB miss rate PMC0/FIXC0 +L1 ITLB miss duration [Cyc] PMC1/PMC0 + + +LONG +Formulas: +L1 ITLB misses = ITLB_MISSES_CAUSES_A_WALK +L1 ITLB miss rate = ITLB_MISSES_CAUSES_A_WALK / INSTR_RETIRED_ANY +L1 ITLB miss duration [Cyc] = ITLB_MISSES_WALK_DURATION / ITLB_MISSES_CAUSES_A_WALK +- +The ITLB miss rates gives a measure how often a TLB miss occurred +per instruction. The duration measures the time in cycles how long a walk did take. + diff --git a/collectors/likwid/groups/broadwellD/TMA.txt b/collectors/likwid/groups/broadwellD/TMA.txt new file mode 100644 index 0000000..afb4126 --- /dev/null +++ b/collectors/likwid/groups/broadwellD/TMA.txt @@ -0,0 +1,48 @@ +SHORT Top down cycle allocation + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 UOPS_ISSUED_ANY +PMC1 UOPS_RETIRED_RETIRE_SLOTS +PMC2 IDQ_UOPS_NOT_DELIVERED_CORE +PMC3 INT_MISC_RECOVERY_CYCLES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +IPC FIXC0/FIXC1 +Total Slots 4*FIXC1 +Slots Retired PMC1 +Fetch Bubbles PMC2 +Recovery Bubbles 4*PMC3 +Front End [%] PMC2/(4*FIXC1)*100 +Speculation [%] (PMC0-PMC1+(4*PMC3))/(4*FIXC1)*100 +Retiring [%] PMC1/(4*FIXC1)*100 +Back End [%] (1-((PMC2+PMC0+(4*PMC3))/(4*FIXC1)))*100 + +LONG +Formulas: +Total Slots = 4*CPU_CLK_UNHALTED_CORE +Slots Retired = UOPS_RETIRED_RETIRE_SLOTS +Fetch Bubbles = IDQ_UOPS_NOT_DELIVERED_CORE +Recovery Bubbles = 4*INT_MISC_RECOVERY_CYCLES +Front End [%] = IDQ_UOPS_NOT_DELIVERED_CORE/(4*CPU_CLK_UNHALTED_CORE)*100 +Speculation [%] = (UOPS_ISSUED_ANY-UOPS_RETIRED_RETIRE_SLOTS+(4*INT_MISC_RECOVERY_CYCLES))/(4*CPU_CLK_UNHALTED_CORE)*100 +Retiring [%] = UOPS_RETIRED_RETIRE_SLOTS/(4*CPU_CLK_UNHALTED_CORE)*100 +Back End [%] = (1-((IDQ_UOPS_NOT_DELIVERED_CORE+UOPS_ISSUED_ANY+(4*INT_MISC_RECOVERY_CYCLES))/(4*CPU_CLK_UNHALTED_CORE)))*100 +-- +This performance group measures cycles to determine percentage of time spent in +front end, back end, retiring and speculation. These metrics are published and +verified by Intel. Further information: +Webpage describing Top-Down Method and its usage in Intel vTune: +https://software.intel.com/en-us/vtune-amplifier-help-tuning-applications-using-a-top-down-microarchitecture-analysis-method +Paper by Yasin Ahmad: +https://sites.google.com/site/analysismethods/yasin-pubs/TopDown-Yasin-ISPASS14.pdf?attredirects=0 +Slides by Yasin Ahmad: +http://www.cs.technion.ac.il/~erangi/TMA_using_Linux_perf__Ahmad_Yasin.pdf +The performance group was originally published here: +http://perf.mvermeulen.com/2018/04/14/top-down-performance-counter-analysis-part-1-likwid/ diff --git a/collectors/likwid/groups/broadwellD/UOPS.txt b/collectors/likwid/groups/broadwellD/UOPS.txt new file mode 100644 index 0000000..e6cc208 --- /dev/null +++ b/collectors/likwid/groups/broadwellD/UOPS.txt @@ -0,0 +1,35 @@ +SHORT UOPs execution info + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 UOPS_ISSUED_ANY +PMC1 UOPS_EXECUTED_THREAD +PMC2 UOPS_RETIRED_ALL +PMC3 UOPS_ISSUED_FLAGS_MERGE + + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Issued UOPs PMC0 +Merged UOPs PMC3 +Executed UOPs PMC1 +Retired UOPs PMC2 + +LONG +Formulas: +Issued UOPs = UOPS_ISSUED_ANY +Merged UOPs = UOPS_ISSUED_FLAGS_MERGE +Executed UOPs = UOPS_EXECUTED_THREAD +Retired UOPs = UOPS_RETIRED_ALL +- +This group returns information about the instruction pipeline. It measures the +issued, executed and retired uOPs and returns the number of uOPs which were issued +but not executed as well as the number of uOPs which were executed but never retired. +The executed but not retired uOPs commonly come from speculatively executed branches. + diff --git a/collectors/likwid/groups/broadwellEP/BRANCH.txt b/collectors/likwid/groups/broadwellEP/BRANCH.txt new file mode 100644 index 0000000..b8d41b2 --- /dev/null +++ b/collectors/likwid/groups/broadwellEP/BRANCH.txt @@ -0,0 +1,31 @@ +SHORT Branch prediction miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 BR_INST_RETIRED_ALL_BRANCHES +PMC1 BR_MISP_RETIRED_ALL_BRANCHES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Branch rate PMC0/FIXC0 +Branch misprediction rate PMC1/FIXC0 +Branch misprediction ratio PMC1/PMC0 +Instructions per branch FIXC0/PMC0 + +LONG +Formulas: +Branch rate = BR_INST_RETIRED_ALL_BRANCHES/INSTR_RETIRED_ANY +Branch misprediction rate = BR_MISP_RETIRED_ALL_BRANCHES/INSTR_RETIRED_ANY +Branch misprediction ratio = BR_MISP_RETIRED_ALL_BRANCHES/BR_INST_RETIRED_ALL_BRANCHES +Instructions per branch = INSTR_RETIRED_ANY/BR_INST_RETIRED_ALL_BRANCHES +- +The rates state how often on average a branch or a mispredicted branch occurred +per instruction retired in total. The branch misprediction ratio sets directly +into relation what ratio of all branch instruction where mispredicted. +Instructions per branch is 1/branch rate. + diff --git a/collectors/likwid/groups/broadwellEP/CACHES.txt b/collectors/likwid/groups/broadwellEP/CACHES.txt new file mode 100644 index 0000000..6a14e52 --- /dev/null +++ b/collectors/likwid/groups/broadwellEP/CACHES.txt @@ -0,0 +1,135 @@ +SHORT Cache bandwidth in MBytes/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 L1D_REPLACEMENT +PMC1 L2_TRANS_L1D_WB +PMC2 L2_LINES_IN_ALL +PMC3 L2_TRANS_L2_WB +CBOX0C1 LLC_VICTIMS_M +CBOX1C1 LLC_VICTIMS_M +CBOX2C1 LLC_VICTIMS_M +CBOX3C1 LLC_VICTIMS_M +CBOX4C1 LLC_VICTIMS_M +CBOX5C1 LLC_VICTIMS_M +CBOX6C1 LLC_VICTIMS_M +CBOX7C1 LLC_VICTIMS_M +CBOX8C1 LLC_VICTIMS_M +CBOX9C1 LLC_VICTIMS_M +CBOX10C1 LLC_VICTIMS_M +CBOX11C1 LLC_VICTIMS_M +CBOX12C1 LLC_VICTIMS_M +CBOX13C1 LLC_VICTIMS_M +CBOX14C1 LLC_VICTIMS_M +CBOX15C1 LLC_VICTIMS_M +CBOX16C1 LLC_VICTIMS_M +CBOX17C1 LLC_VICTIMS_M +CBOX18C1 LLC_VICTIMS_M +CBOX19C1 LLC_VICTIMS_M +CBOX20C1 LLC_VICTIMS_M +CBOX21C1 LLC_VICTIMS_M +CBOX0C0 LLC_LOOKUP_DATA_READ +CBOX1C0 LLC_LOOKUP_DATA_READ +CBOX2C0 LLC_LOOKUP_DATA_READ +CBOX3C0 LLC_LOOKUP_DATA_READ +CBOX4C0 LLC_LOOKUP_DATA_READ +CBOX5C0 LLC_LOOKUP_DATA_READ +CBOX6C0 LLC_LOOKUP_DATA_READ +CBOX7C0 LLC_LOOKUP_DATA_READ +CBOX8C0 LLC_LOOKUP_DATA_READ +CBOX9C0 LLC_LOOKUP_DATA_READ +CBOX10C0 LLC_LOOKUP_DATA_READ +CBOX11C0 LLC_LOOKUP_DATA_READ +CBOX12C0 LLC_LOOKUP_DATA_READ +CBOX13C0 LLC_LOOKUP_DATA_READ +CBOX14C0 LLC_LOOKUP_DATA_READ +CBOX15C0 LLC_LOOKUP_DATA_READ +CBOX16C0 LLC_LOOKUP_DATA_READ +CBOX17C0 LLC_LOOKUP_DATA_READ +CBOX18C0 LLC_LOOKUP_DATA_READ +CBOX19C0 LLC_LOOKUP_DATA_READ +CBOX20C0 LLC_LOOKUP_DATA_READ +CBOX21C0 LLC_LOOKUP_DATA_READ +MBOX0C0 CAS_COUNT_RD +MBOX0C1 CAS_COUNT_WR +MBOX1C0 CAS_COUNT_RD +MBOX1C1 CAS_COUNT_WR +MBOX2C0 CAS_COUNT_RD +MBOX2C1 CAS_COUNT_WR +MBOX3C0 CAS_COUNT_RD +MBOX3C1 CAS_COUNT_WR +MBOX4C0 CAS_COUNT_RD +MBOX4C1 CAS_COUNT_WR +MBOX5C0 CAS_COUNT_RD +MBOX5C1 CAS_COUNT_WR +MBOX6C0 CAS_COUNT_RD +MBOX6C1 CAS_COUNT_WR +MBOX7C0 CAS_COUNT_RD +MBOX7C1 CAS_COUNT_WR + + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L2 to L1 load bandwidth [MBytes/s] 1.0E-06*PMC0*64.0/time +L2 to L1 load data volume [GBytes] 1.0E-09*PMC0*64.0 +L1 to L2 evict bandwidth [MBytes/s] 1.0E-06*PMC1*64.0/time +L1 to L2 evict data volume [GBytes] 1.0E-09*PMC1*64.0 +L1 to/from L2 bandwidth [MBytes/s] 1.0E-06*(PMC0+PMC1)*64.0/time +L1 to/from L2 data volume [GBytes] 1.0E-09*(PMC0+PMC1)*64.0 +L3 to L2 load bandwidth [MBytes/s] 1.0E-06*PMC2*64.0/time +L3 to L2 load data volume [GBytes] 1.0E-09*PMC2*64.0 +L2 to L3 evict bandwidth [MBytes/s] 1.0E-06*PMC3*64.0/time +L2 to L3 evict data volume [GBytes] 1.0E-09*PMC3*64.0 +L2 to/from L3 bandwidth [MBytes/s] 1.0E-06*(PMC2+PMC3)*64.0/time +L2 to/from L3 data volume [GBytes] 1.0E-09*(PMC2+PMC3)*64.0 +System to L3 bandwidth [MBytes/s] 1.0E-06*(CBOX0C0+CBOX1C0+CBOX2C0+CBOX3C0+CBOX4C0+CBOX5C0+CBOX6C0+CBOX7C0+CBOX8C0+CBOX9C0+CBOX10C0+CBOX11C0+CBOX12C0+CBOX13C0+CBOX14C0+CBOX15C0+CBOX16C0+CBOX17C0+CBOX18C0+CBOX19C0+CBOX20C0+CBOX21C0)*64.0/time +System to L3 data volume [GBytes] 1.0E-09*(CBOX0C0+CBOX1C0+CBOX2C0+CBOX3C0+CBOX4C0+CBOX5C0+CBOX6C0+CBOX7C0+CBOX8C0+CBOX9C0+CBOX10C0+CBOX11C0+CBOX12C0+CBOX13C0+CBOX14C0+CBOX15C0+CBOX16C0+CBOX17C0+CBOX18C0+CBOX19C0+CBOX20C0+CBOX21C0)*64.0 +L3 to system bandwidth [MBytes/s] 1.0E-06*(CBOX0C1+CBOX1C1+CBOX2C1+CBOX3C1+CBOX4C1+CBOX5C1+CBOX6C1+CBOX7C1+CBOX8C1+CBOX9C1+CBOX10C1+CBOX11C1+CBOX12C1+CBOX13C1+CBOX14C1+CBOX15C1+CBOX16C1+CBOX17C1+CBOX18C1+CBOX19C1+CBOX20C1+CBOX21C1)*64/time +L3 to system data volume [GBytes] 1.0E-09*(CBOX0C1+CBOX1C1+CBOX2C1+CBOX3C1+CBOX4C1+CBOX5C1+CBOX6C1+CBOX7C1+CBOX8C1+CBOX9C1+CBOX10C1+CBOX11C1+CBOX12C1+CBOX13C1+CBOX14C1+CBOX15C1+CBOX16C1+CBOX17C1+CBOX18C1+CBOX19C1+CBOX20C1+CBOX21C1)*64 +L3 to/from system bandwidth [MBytes/s] 1.0E-06*(CBOX0C0+CBOX1C0+CBOX2C0+CBOX3C0+CBOX4C0+CBOX5C0+CBOX6C0+CBOX7C0+CBOX8C0+CBOX9C0+CBOX10C0+CBOX11C0+CBOX12C0+CBOX13C0+CBOX14C0+CBOX15C0+CBOX16C0+CBOX17C0+CBOX18C0+CBOX19C0+CBOX20C0+CBOX21C0+CBOX0C1+CBOX1C1+CBOX2C1+CBOX3C1+CBOX4C1+CBOX5C1+CBOX6C1+CBOX7C1+CBOX8C1+CBOX9C1+CBOX10C1+CBOX11C1+CBOX12C1+CBOX13C1+CBOX14C1+CBOX15C1+CBOX16C1+CBOX17C1+CBOX18C1+CBOX19C1+CBOX20C1+CBOX21C1)*64.0/time +L3 to/from system data volume [GBytes] 1.0E-09*(CBOX0C0+CBOX1C0+CBOX2C0+CBOX3C0+CBOX4C0+CBOX5C0+CBOX6C0+CBOX7C0+CBOX8C0+CBOX9C0+CBOX10C0+CBOX11C0+CBOX12C0+CBOX13C0+CBOX14C0+CBOX15C0+CBOX16C0+CBOX17C0+CBOX18C0+CBOX19C0+CBOX20C0+CBOX21C0+CBOX0C1+CBOX1C1+CBOX2C1+CBOX3C1+CBOX4C1+CBOX5C1+CBOX6C1+CBOX7C1+CBOX8C1+CBOX9C1+CBOX10C1+CBOX11C1+CBOX12C1+CBOX13C1+CBOX14C1+CBOX15C1+CBOX16C1+CBOX17C1+CBOX18C1+CBOX19C1+CBOX20C1+CBOX21C1)*64.0 +Memory read bandwidth [MBytes/s] 1.0E-06*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX6C0+MBOX7C0)*64.0/time +Memory read data volume [GBytes] 1.0E-09*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX6C0+MBOX7C0)*64.0 +Memory write bandwidth [MBytes/s] 1.0E-06*(MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1+MBOX6C1+MBOX7C1)*64.0/time +Memory write data volume [GBytes] 1.0E-09*(MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1+MBOX6C1+MBOX7C1)*64.0 +Memory bandwidth [MBytes/s] 1.0E-06*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX6C0+MBOX7C0+MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1+MBOX6C1+MBOX7C1)*64.0/time +Memory data volume [GBytes] 1.0E-09*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX6C0+MBOX7C0+MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1+MBOX6C1+MBOX7C1)*64.0 + +LONG +Formulas: +L2 to L1 load bandwidth [MBytes/s] = 1.0E-06*L1D_REPLACEMENT*64/time +L2 to L1 load data volume [GBytes] = 1.0E-09*L1D_REPLACEMENT*64 +L1 to L2 evict bandwidth [MBytes/s] = 1.0E-06*L1D_M_EVICT*64/time +L1 to L2 evict data volume [GBytes] = 1.0E-09*L1D_M_EVICT*64 +L1 to/from L2 bandwidth [MBytes/s] = 1.0E-06*(L1D_REPLACEMENT+L1D_M_EVICT)*64/time +L1 to/from L2 data volume [GBytes] = 1.0E-09*(L1D_REPLACEMENT+L1D_M_EVICT)*64 +L3 to L2 load bandwidth [MBytes/s] = 1.0E-06*L2_LINES_IN_ALL*64/time +L3 to L2 load data volume [GBytes] = 1.0E-09*L2_LINES_IN_ALL*64 +L2 to L3 evict bandwidth [MBytes/s] = 1.0E-06*L2_TRANS_L2_WB*64/time +L2 to L3 evict data volume [GBytes] = 1.0E-09*L2_TRANS_L2_WB*64 +L2 to/from L3 bandwidth [MBytes/s] = 1.0E-06*(L2_LINES_IN_ALL+L2_TRANS_L2_WB)*64/time +L2 to/from L3 data volume [GBytes] = 1.0E-09*(L2_LINES_IN_ALL+L2_TRANS_L2_WB)*64 +System to L3 bandwidth [MBytes/s] = 1.0E-06*(SUM(LLC_LOOKUP_DATA_READ))*64/time +System to L3 data volume [GBytes] = 1.0E-09*(SUM(LLC_LOOKUP_DATA_READ))*64 +L3 to system bandwidth [MBytes/s] = 1.0E-06*(SUM(LLC_VICTIMS_M))*64/time +L3 to system data volume [GBytes] = 1.0E-09*(SUM(LLC_VICTIMS_M))*64 +L3 to/from system bandwidth [MBytes/s] = 1.0E-06*(SUM(LLC_LOOKUP_DATA_READ)+SUM(LLC_VICTIMS_M))*64/time +L3 to/from system data volume [GBytes] = 1.0E-09*(SUM(LLC_LOOKUP_DATA_READ)+SUM(LLC_VICTIMS_M))*64 +Memory read bandwidth [MBytes/s] = 1.0E-06*(SUM(CAS_COUNT_RD))*64.0/time +Memory read data volume [GBytes] = 1.0E-09*(SUM(CAS_COUNT_RD))*64.0 +Memory write bandwidth [MBytes/s] = 1.0E-06*(SUM(CAS_COUNT_WR))*64.0/time +Memory write data volume [GBytes] = 1.0E-09*(SUM(CAS_COUNT_WR))*64.0 +Memory bandwidth [MBytes/s] = 1.0E-06*(SUM(CAS_COUNT_RD)+SUM(CAS_COUNT_WR))*64.0/time +Memory data volume [GBytes] = 1.0E-09*(SUM(CAS_COUNT_RD)+SUM(CAS_COUNT_WR))*64.0 +- +Group to measure cache transfers between L1 and Memory. Please notice that the +L3 to/from system metrics contain any traffic to the system (memory, +Intel QPI, etc.) but don't seem to handle anything because commonly memory read +bandwidth and L3 to L2 bandwidth is higher as the memory to L3 bandwidth. + diff --git a/collectors/likwid/groups/broadwellEP/CLOCK.txt b/collectors/likwid/groups/broadwellEP/CLOCK.txt new file mode 100644 index 0000000..b81bee6 --- /dev/null +++ b/collectors/likwid/groups/broadwellEP/CLOCK.txt @@ -0,0 +1,26 @@ +SHORT Power and Energy consumption + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PWR0 PWR_PKG_ENERGY +UBOXFIX UNCORE_CLOCK + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +Uncore Clock [MHz] 1.E-06*UBOXFIX/time +CPI FIXC1/FIXC0 +Energy [J] PWR0 +Power [W] PWR0/time + +LONG +Formulas: +Power = PWR_PKG_ENERGY / time +Uncore Clock [MHz] = 1.E-06 * UNCORE_CLOCK / time +- +Broadwell implements the new RAPL interface. This interface enables to +monitor the consumed energy on the package (socket) level. + diff --git a/collectors/likwid/groups/broadwellEP/CYCLE_ACTIVITY.txt b/collectors/likwid/groups/broadwellEP/CYCLE_ACTIVITY.txt new file mode 100644 index 0000000..c432a44 --- /dev/null +++ b/collectors/likwid/groups/broadwellEP/CYCLE_ACTIVITY.txt @@ -0,0 +1,38 @@ +SHORT Cycle Activities + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 CYCLE_ACTIVITY_CYCLES_L2_PENDING +PMC1 CYCLE_ACTIVITY_CYCLES_LDM_PENDING +PMC2 CYCLE_ACTIVITY_CYCLES_L1D_PENDING +PMC3 CYCLE_ACTIVITY_CYCLES_NO_EXECUTE + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Cycles without execution [%] (PMC3/FIXC1)*100 +Cycles without execution due to L1D [%] (PMC2/FIXC1)*100 +Cycles without execution due to L2 [%] (PMC0/FIXC1)*100 +Cycles without execution due to memory loads [%] (PMC1/FIXC1)*100 + +LONG +Formulas: +Cycles without execution [%] = CYCLE_ACTIVITY_CYCLES_NO_EXECUTE/CPU_CLK_UNHALTED_CORE*100 +Cycles with stalls due to L1D [%] = CYCLE_ACTIVITY_CYCLES_L1D_PENDING/CPU_CLK_UNHALTED_CORE*100 +Cycles with stalls due to L2 [%] = CYCLE_ACTIVITY_CYCLES_L2_PENDING/CPU_CLK_UNHALTED_CORE*100 +Cycles without execution due to memory loads [%] = CYCLE_ACTIVITY_CYCLES_LDM_PENDING/CPU_CLK_UNHALTED_CORE*100 +-- +This performance group measures the cycles while waiting for data from the cache +and memory hierarchy. +CYCLE_ACTIVITY_CYCLES_NO_EXECUTE: Counts number of cycles nothing is executed on +any execution port. +CYCLE_ACTIVITY_CYCLES_L1D_PENDING: Cycles while L1 cache miss demand load is +outstanding. +CYCLE_ACTIVITY_CYCLES_L2_PENDING: Cycles while L2 cache miss demand load is +outstanding. +CYCLE_ACTIVITY_CYCLES_LDM_PENDING: Cycles while memory subsystem has an +outstanding load. diff --git a/collectors/likwid/groups/broadwellEP/CYCLE_STALLS.txt b/collectors/likwid/groups/broadwellEP/CYCLE_STALLS.txt new file mode 100644 index 0000000..795aeb9 --- /dev/null +++ b/collectors/likwid/groups/broadwellEP/CYCLE_STALLS.txt @@ -0,0 +1,45 @@ +SHORT Cycle Activities (Stalls) + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 CYCLE_ACTIVITY_STALLS_L2_PENDING +PMC1 CYCLE_ACTIVITY_STALLS_LDM_PENDING +PMC2 CYCLE_ACTIVITY_STALLS_L1D_PENDING +PMC3 CYCLE_ACTIVITY_STALLS_TOTAL + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Total execution stalls PMC3 +Stalls caused by L1D misses [%] (PMC2/PMC3)*100 +Stalls caused by L2 misses [%] (PMC0/PMC3)*100 +Stalls caused by memory loads [%] (PMC1/PMC3)*100 +Execution stall rate [%] (PMC3/FIXC1)*100 +Stalls caused by L1D misses rate [%] (PMC2/FIXC1)*100 +Stalls caused by L2 misses rate [%] (PMC0/FIXC1)*100 +Stalls caused by memory loads rate [%] (PMC1/FIXC1)*100 + +LONG +Formulas: +Total execution stalls = CYCLE_ACTIVITY_STALLS_TOTAL +Stalls caused by L1D misses [%] = (CYCLE_ACTIVITY_STALLS_L1D_PENDING/CYCLE_ACTIVITY_STALLS_TOTAL)*100 +Stalls caused by L2 misses [%] = (CYCLE_ACTIVITY_STALLS_L2_PENDING/CYCLE_ACTIVITY_STALLS_TOTAL)*100 +Stalls caused by memory loads [%] = (CYCLE_ACTIVITY_STALLS_LDM_PENDING/CYCLE_ACTIVITY_STALLS_TOTAL)*100 +Execution stall rate [%] = (CYCLE_ACTIVITY_STALLS_TOTAL/CPU_CLK_UNHALTED_CORE)*100 +Stalls caused by L1D misses rate [%] = (CYCLE_ACTIVITY_STALLS_L1D_PENDING/CPU_CLK_UNHALTED_CORE)*100 +Stalls caused by L2 misses rate [%] = (CYCLE_ACTIVITY_STALLS_L2_PENDING/CPU_CLK_UNHALTED_CORE)*100 +Stalls caused by memory loads rate [%] = (CYCLE_ACTIVITY_STALLS_LDM_PENDING/CPU_CLK_UNHALTED_CORE)*100 +-- +This performance group measures the stalls caused by data traffic in the cache +hierarchy. +CYCLE_ACTIVITY_STALLS_TOTAL: Total execution stalls. +CYCLE_ACTIVITY_STALLS_L1D_PENDING: Execution stalls while L1 cache miss demand +load is outstanding. +CYCLE_ACTIVITY_STALLS_L2_PENDING: Execution stalls while L2 cache miss demand +load is outstanding. +CYCLE_ACTIVITY_STALLS_LDM_PENDING: Execution stalls while memory subsystem has +an outstanding load. diff --git a/collectors/likwid/groups/broadwellEP/DATA.txt b/collectors/likwid/groups/broadwellEP/DATA.txt new file mode 100644 index 0000000..6955eb7 --- /dev/null +++ b/collectors/likwid/groups/broadwellEP/DATA.txt @@ -0,0 +1,22 @@ +SHORT Load to store ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 MEM_UOPS_RETIRED_LOADS_ALL +PMC1 MEM_UOPS_RETIRED_STORES_ALL + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Load to store ratio PMC0/PMC1 + +LONG +Formulas: +Load to store ratio = MEM_UOPS_RETIRED_LOADS_ALL/MEM_UOPS_RETIRED_STORES_ALL +- +This is a metric to determine your load to store ratio. + diff --git a/collectors/likwid/groups/broadwellEP/DIVIDE.txt b/collectors/likwid/groups/broadwellEP/DIVIDE.txt new file mode 100644 index 0000000..c7c5fb2 --- /dev/null +++ b/collectors/likwid/groups/broadwellEP/DIVIDE.txt @@ -0,0 +1,24 @@ +SHORT Divide unit information + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0:EDGEDETECT ARITH_FPU_DIV_ACTIVE +PMC1 ARITH_FPU_DIV_ACTIVE + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Number of divide ops PMC0:EDGEDETECT +Avg. divide unit usage duration PMC1/PMC0:EDGEDETECT + +LONG +Formulas: +Number of divide ops = ARITH_FPU_DIV_ACTIVE:EDGEDETECT +Avg. divide unit usage duration = ARITH_FPU_DIV_ACTIVE/ARITH_FPU_DIV_ACTIVE:EDGEDETECT +- +This performance group measures the average latency of divide operations diff --git a/collectors/likwid/groups/broadwellEP/ENERGY.txt b/collectors/likwid/groups/broadwellEP/ENERGY.txt new file mode 100644 index 0000000..fe7829f --- /dev/null +++ b/collectors/likwid/groups/broadwellEP/ENERGY.txt @@ -0,0 +1,35 @@ +SHORT Power and Energy consumption + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +TMP0 TEMP_CORE +PWR0 PWR_PKG_ENERGY +PWR1 PWR_PP0_ENERGY +PWR3 PWR_DRAM_ENERGY + + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Temperature [C] TMP0 +Energy [J] PWR0 +Power [W] PWR0/time +Energy PP0 [J] PWR1 +Power PP0 [W] PWR1/time +Energy DRAM [J] PWR3 +Power DRAM [W] PWR3/time + +LONG +Formulas: +Power = PWR_PKG_ENERGY / time +Power PP0 = PWR_PP0_ENERGY / time +Power DRAM = PWR_DRAM_ENERGY / time +- +Broadwell implements the new RAPL interface. This interface enables to +monitor the consumed energy on the package (socket) and DRAM level. + diff --git a/collectors/likwid/groups/broadwellEP/FALSE_SHARE.txt b/collectors/likwid/groups/broadwellEP/FALSE_SHARE.txt new file mode 100644 index 0000000..602b606 --- /dev/null +++ b/collectors/likwid/groups/broadwellEP/FALSE_SHARE.txt @@ -0,0 +1,30 @@ +SHORT False sharing + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 MEM_LOAD_UOPS_L3_HIT_RETIRED_XSNP_HITM +PMC1 MEM_LOAD_UOPS_L3_MISS_RETIRED_REMOTE_HITM +PMC2 MEM_UOPS_RETIRED_LOADS_ALL + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Local LLC false sharing [MByte] 1.E-06*PMC0*64 +Local LLC false sharing rate PMC0/PMC2 +Remote LLC false sharing [MByte] 1.E-06*PMC1*64 +Remote LLC false sharing rate PMC1/PMC2 + +LONG +Formulas: +Local LLC false sharing [MByte] = 1.E-06*MEM_LOAD_UOPS_L3_HIT_RETIRED_XSNP_HITM*64 +Local LLC false sharing rate = MEM_LOAD_UOPS_L3_HIT_RETIRED_XSNP_HITM/MEM_UOPS_RETIRED_LOADS_ALL +Remote LLC false sharing [MByte] = 1.E-06*MEM_LOAD_UOPS_L3_MISS_RETIRED_REMOTE_HITM*64 +Remote LLC false sharing rate = MEM_LOAD_UOPS_L3_MISS_RETIRED_REMOTE_HITM/MEM_LOAD_UOPS_RETIRED_ALL +- +False-sharing of cache lines can dramatically reduce the performance of an +application. This performance group measures the L3 traffic induced by false-sharing. +The false-sharing rate uses all memory load UOPs as reference. diff --git a/collectors/likwid/groups/broadwellEP/FLOPS_AVX.txt b/collectors/likwid/groups/broadwellEP/FLOPS_AVX.txt new file mode 100644 index 0000000..7854608 --- /dev/null +++ b/collectors/likwid/groups/broadwellEP/FLOPS_AVX.txt @@ -0,0 +1,24 @@ +SHORT Packed AVX MFLOP/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE +PMC1 FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Packed SP [MFLOP/s] 1.0E-06*(PMC0*8.0)/time +Packed DP [MFLOP/s] 1.0E-06*(PMC1*4.0)/time + +LONG +Formulas: +Packed SP [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE*8)/runtime +Packed DP [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE*4)/runtime +- +FLOP rates of 256 bit packed floating-point instructions + diff --git a/collectors/likwid/groups/broadwellEP/FLOPS_DP.txt b/collectors/likwid/groups/broadwellEP/FLOPS_DP.txt new file mode 100644 index 0000000..348ec76 --- /dev/null +++ b/collectors/likwid/groups/broadwellEP/FLOPS_DP.txt @@ -0,0 +1,31 @@ +SHORT Double Precision MFLOP/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 FP_ARITH_INST_RETIRED_128B_PACKED_DOUBLE +PMC1 FP_ARITH_INST_RETIRED_SCALAR_DOUBLE +PMC2 FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +DP [MFLOP/s] 1.0E-06*(PMC0*2.0+PMC1+PMC2*4.0)/time +AVX DP [MFLOP/s] 1.0E-06*(PMC2*4.0)/time +Packed [MUOPS/s] 1.0E-06*(PMC0+PMC2)/time +Scalar [MUOPS/s] 1.0E-06*PMC1/time +Vectorization ratio 100*(PMC0+PMC2)/(PMC0+PMC1+PMC2) + +LONG +Formulas: +DP [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_128B_PACKED_DOUBLE*2+FP_ARITH_INST_RETIRED_SCALAR_DOUBLE+FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE*4)/runtime +AVX DP [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE*4)/runtime +Packed [MUOPS/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_128B_PACKED_DOUBLE+FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE)/runtime +Scalar [MUOPS/s] = 1.0E-06*FP_ARITH_INST_RETIRED_SCALAR_DOUBLE/runtime +Vectorization ratio = 100*(FP_ARITH_INST_RETIRED_128B_PACKED_DOUBLE+FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE)/(FP_ARITH_INST_RETIRED_SCALAR_DOUBLE+FP_ARITH_INST_RETIRED_128B_PACKED_DOUBLE+FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE) +- +AVX/SSE scalar and packed double precision FLOP rates. + diff --git a/collectors/likwid/groups/broadwellEP/FLOPS_SP.txt b/collectors/likwid/groups/broadwellEP/FLOPS_SP.txt new file mode 100644 index 0000000..1d7fd7c --- /dev/null +++ b/collectors/likwid/groups/broadwellEP/FLOPS_SP.txt @@ -0,0 +1,31 @@ +SHORT Single Precision MFLOP/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 FP_ARITH_INST_RETIRED_128B_PACKED_SINGLE +PMC1 FP_ARITH_INST_RETIRED_SCALAR_SINGLE +PMC2 FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +SP [MFLOP/s] 1.0E-06*(PMC0*4.0+PMC1+PMC2*8.0)/time +AVX SP [MFLOP/s] 1.0E-06*(PMC2*8.0)/time +Packed [MUOPS/s] 1.0E-06*(PMC0+PMC2)/time +Scalar [MUOPS/s] 1.0E-06*PMC1/time +Vectorization ratio 100*(PMC0+PMC2)/(PMC0+PMC1+PMC2) + +LONG +Formulas: +SP [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_128B_PACKED_SINGLE*4+FP_ARITH_INST_RETIRED_SCALAR_SINGLE+FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE*8)/runtime +AVX SP [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE*8)/runtime +Packed [MUOPS/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_128B_PACKED_SINGLE+FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE)/runtime +Scalar [MUOPS/s] = 1.0E-06*FP_ARITH_INST_RETIRED_SCALAR_SINGLE/runtime +Vectorization ratio [%] = 100*(FP_ARITH_INST_RETIRED_128B_PACKED_SINGLE+FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE)/(FP_ARITH_INST_RETIRED_SCALAR_SINGLE+FP_ARITH_INST_RETIRED_128B_PACKED_SINGLE+FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE) +- +AVX/SSE scalar and packed single precision FLOP rates. + diff --git a/collectors/likwid/groups/broadwellEP/HA.txt b/collectors/likwid/groups/broadwellEP/HA.txt new file mode 100644 index 0000000..1e5a700 --- /dev/null +++ b/collectors/likwid/groups/broadwellEP/HA.txt @@ -0,0 +1,40 @@ +SHORT Main memory bandwidth in MBytes/s seen from Home agent + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +BBOX0C0 IMC_READS_NORMAL +BBOX0C1 BYPASS_IMC_TAKEN +BBOX0C2 IMC_WRITES_ALL +BBOX1C0 IMC_READS_NORMAL +BBOX1C1 BYPASS_IMC_TAKEN +BBOX1C2 IMC_WRITES_ALL + + + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Memory read bandwidth [MBytes/s] 1.0E-06*(BBOX0C0+BBOX1C0+BBOX0C1+BBOX1C1)*64.0/time +Memory read data volume [GBytes] 1.0E-09*(BBOX0C0+BBOX1C0+BBOX0C1+BBOX1C1)*64.0 +Memory write bandwidth [MBytes/s] 1.0E-06*(BBOX0C2+BBOX1C2)*64.0/time +Memory write data volume [GBytes] 1.0E-09*(BBOX0C2+BBOX1C2)*64.0 +Memory bandwidth [MBytes/s] 1.0E-06*(BBOX0C0+BBOX1C0+BBOX0C1+BBOX1C1+BBOX0C2+BBOX1C2)*64.0/time +Memory data volume [GBytes] 1.0E-09*(BBOX0C0+BBOX1C0+BBOX0C1+BBOX1C1+BBOX0C2+BBOX1C2)*64.0 + +LONG +Formulas: +Memory read bandwidth [MBytes/s] = 1.0E-06*(SUM(IMC_READS_NORMAL)+SUM(BYPASS_IMC_TAKEN))*64.0/time +Memory read data volume [GBytes] = 1.0E-09*(SUM(IMC_READS_NORMAL)+SUM(BYPASS_IMC_TAKEN))*64.0 +Memory write bandwidth [MBytes/s] = 1.0E-06*(SUM(IMC_WRITES_ALL))*64.0/time +Memory write data volume [GBytes] = 1.0E-09*(SUM(IMC_WRITES_ALL))*64.0 +Memory bandwidth [MBytes/s] = 1.0E-06*(SUM(IMC_READS_NORMAL) + SUM(BYPASS_IMC_TAKEN) + SUM(IMC_WRITES_ALL))*64.0/time +Memory data volume [GBytes] = 1.0E-09*(SUM(IMC_READS_NORMAL) + SUM(BYPASS_IMC_TAKEN) + SUM(IMC_WRITES_ALL))*64.0 +- +This group derives the same metrics as the MEM group but use the events of the +Home Agent, a central unit that is responsible for the protocol side of memory +interactions. diff --git a/collectors/likwid/groups/broadwellEP/ICACHE.txt b/collectors/likwid/groups/broadwellEP/ICACHE.txt new file mode 100644 index 0000000..5f11ad6 --- /dev/null +++ b/collectors/likwid/groups/broadwellEP/ICACHE.txt @@ -0,0 +1,25 @@ +SHORT Instruction cache miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 ICACHE_ACCESSES +PMC1 ICACHE_MISSES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L1I request rate PMC0/FIXC0 +L1I miss rate PMC1/FIXC0 +L1I miss ratio PMC1/PMC0 + +LONG +Formulas: +L1I request rate = ICACHE_ACCESSES / INSTR_RETIRED_ANY +L1I miss rate = ICACHE_MISSES / INSTR_RETIRED_ANY +L1I miss ratio = ICACHE_MISSES / ICACHE_ACCESSES +- +This group measures some L1 instruction cache metrics. diff --git a/collectors/likwid/groups/broadwellEP/L2.txt b/collectors/likwid/groups/broadwellEP/L2.txt new file mode 100644 index 0000000..60c7f79 --- /dev/null +++ b/collectors/likwid/groups/broadwellEP/L2.txt @@ -0,0 +1,37 @@ +SHORT L2 cache bandwidth in MBytes/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 L1D_REPLACEMENT +PMC1 L2_TRANS_L1D_WB +PMC2 ICACHE_MISSES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L2D load bandwidth [MBytes/s] 1.0E-06*PMC0*64.0/time +L2D load data volume [GBytes] 1.0E-09*PMC0*64.0 +L2D evict bandwidth [MBytes/s] 1.0E-06*PMC1*64.0/time +L2D evict data volume [GBytes] 1.0E-09*PMC1*64.0 +L2 bandwidth [MBytes/s] 1.0E-06*(PMC0+PMC1+PMC2)*64.0/time +L2 data volume [GBytes] 1.0E-09*(PMC0+PMC1+PMC2)*64.0 + +LONG +Formulas: +L2D load bandwidth [MBytes/s] = 1.0E-06*L1D_REPLACEMENT*64.0/time +L2D load data volume [GBytes] = 1.0E-09*L1D_REPLACEMENT*64.0 +L2D evict bandwidth [MBytes/s] = 1.0E-06*L2_TRANS_L1D_WB*64.0/time +L2D evict data volume [GBytes] = 1.0E-09*L2_TRANS_L1D_WB*64.0 +L2 bandwidth [MBytes/s] = 1.0E-06*(L1D_REPLACEMENT+L2_TRANS_L1D_WB+ICACHE_MISSES)*64.0/time +L2 data volume [GBytes] = 1.0E-09*(L1D_REPLACEMENT+L2_TRANS_L1D_WB+ICACHE_MISSES)*64.0 +- +Profiling group to measure L2 cache bandwidth. The bandwidth is computed by the +number of cache line loaded from the L2 to the L2 data cache and the writebacks from +the L2 data cache to the L2 cache. The group also outputs total data volume transferred between +L2 and L1. Note that this bandwidth also includes data transfers due to a write +allocate load on a store miss in L1 and cache lines transferred it the instruction +cache. diff --git a/collectors/likwid/groups/broadwellEP/L2CACHE.txt b/collectors/likwid/groups/broadwellEP/L2CACHE.txt new file mode 100644 index 0000000..9b5dd4b --- /dev/null +++ b/collectors/likwid/groups/broadwellEP/L2CACHE.txt @@ -0,0 +1,34 @@ +SHORT L2 cache miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 L2_TRANS_ALL_REQUESTS +PMC1 L2_RQSTS_MISS + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L2 request rate PMC0/FIXC0 +L2 miss rate PMC1/FIXC0 +L2 miss ratio PMC1/PMC0 + +LONG +Formulas: +L2 request rate = L2_TRANS_ALL_REQUESTS/INSTR_RETIRED_ANY +L2 miss rate = L2_RQSTS_MISS/INSTR_RETIRED_ANY +L2 miss ratio = L2_RQSTS_MISS/L2_TRANS_ALL_REQUESTS +- +This group measures the locality of your data accesses with regard to the +L2 cache. L2 request rate tells you how data intensive your code is +or how many data accesses you have on average per instruction. +The L2 miss rate gives a measure how often it was necessary to get +cache lines from memory. And finally L2 miss ratio tells you how many of your +memory references required a cache line to be loaded from a higher level. +While the# data cache miss rate might be given by your algorithm you should +try to get data cache miss ratio as low as possible by increasing your cache reuse. + + diff --git a/collectors/likwid/groups/broadwellEP/L3.txt b/collectors/likwid/groups/broadwellEP/L3.txt new file mode 100644 index 0000000..98d1d9e --- /dev/null +++ b/collectors/likwid/groups/broadwellEP/L3.txt @@ -0,0 +1,36 @@ +SHORT L3 cache bandwidth in MBytes/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 L2_LINES_IN_ALL +PMC1 L2_TRANS_L2_WB + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L3 load bandwidth [MBytes/s] 1.0E-06*PMC0*64.0/time +L3 load data volume [GBytes] 1.0E-09*PMC0*64.0 +L3 evict bandwidth [MBytes/s] 1.0E-06*PMC1*64.0/time +L3 evict data volume [GBytes] 1.0E-09*PMC1*64.0 +L3 bandwidth [MBytes/s] 1.0E-06*(PMC0+PMC1)*64.0/time +L3 data volume [GBytes] 1.0E-09*(PMC0+PMC1)*64.0 + +LONG +Formulas: +L3 load bandwidth [MBytes/s] = 1.0E-06*L2_LINES_IN_ALL*64.0/time +L3 load data volume [GBytes] = 1.0E-09*L2_LINES_IN_ALL*64.0 +L3 evict bandwidth [MBytes/s] = 1.0E-06*L2_TRANS_L2_WB*64.0/time +L3 evict data volume [GBytes] = 1.0E-09*L2_TRANS_L2_WB*64.0 +L3 bandwidth [MBytes/s] = 1.0E-06*(L2_LINES_IN_ALL+L2_TRANS_L2_WB)*64/time +L3 data volume [GBytes] = 1.0E-09*(L2_LINES_IN_ALL+L2_TRANS_L2_WB)*64 +- +Profiling group to measure L3 cache bandwidth. The bandwidth is computed by the +number of cache line allocated in the L2 and the number of modified cache lines +evicted from the L2. This group also output data volume transferred between the +L3 and measured cores L2 caches. Note that this bandwidth also includes data +transfers due to a write allocate load on a store miss in L2. + diff --git a/collectors/likwid/groups/broadwellEP/L3CACHE.txt b/collectors/likwid/groups/broadwellEP/L3CACHE.txt new file mode 100644 index 0000000..f863daa --- /dev/null +++ b/collectors/likwid/groups/broadwellEP/L3CACHE.txt @@ -0,0 +1,35 @@ +SHORT L3 cache miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 MEM_LOAD_UOPS_RETIRED_L3_ALL +PMC1 MEM_LOAD_UOPS_RETIRED_L3_MISS +PMC2 UOPS_RETIRED_ALL + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L3 request rate PMC0/PMC2 +L3 miss rate PMC1/PMC2 +L3 miss ratio PMC1/PMC0 + +LONG +Formulas: +L3 request rate = MEM_LOAD_UOPS_RETIRED_L3_ALL/UOPS_RETIRED_ALL +L3 miss rate = MEM_LOAD_UOPS_RETIRED_L3_MISS/UOPS_RETIRED_ALL +L3 miss ratio = MEM_LOAD_UOPS_RETIRED_L3_MISS/MEM_LOAD_UOPS_RETIRED_L3_ALL +- +This group measures the locality of your data accesses with regard to the +L3 cache. L3 request rate tells you how data intensive your code is +or how many data accesses you have on average per instruction. +The L3 miss rate gives a measure how often it was necessary to get +cache lines from memory. And finally L3 miss ratio tells you how many of your +memory references required a cache line to be loaded from a higher level. +While the# data cache miss rate might be given by your algorithm you should +try to get data cache miss ratio as low as possible by increasing your cache reuse. + + diff --git a/collectors/likwid/groups/broadwellEP/MEM.txt b/collectors/likwid/groups/broadwellEP/MEM.txt new file mode 100644 index 0000000..2a17a2c --- /dev/null +++ b/collectors/likwid/groups/broadwellEP/MEM.txt @@ -0,0 +1,52 @@ +SHORT Main memory bandwidth in MBytes/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +MBOX0C0 CAS_COUNT_RD +MBOX0C1 CAS_COUNT_WR +MBOX1C0 CAS_COUNT_RD +MBOX1C1 CAS_COUNT_WR +MBOX2C0 CAS_COUNT_RD +MBOX2C1 CAS_COUNT_WR +MBOX3C0 CAS_COUNT_RD +MBOX3C1 CAS_COUNT_WR +MBOX4C0 CAS_COUNT_RD +MBOX4C1 CAS_COUNT_WR +MBOX5C0 CAS_COUNT_RD +MBOX5C1 CAS_COUNT_WR +MBOX6C0 CAS_COUNT_RD +MBOX6C1 CAS_COUNT_WR +MBOX7C0 CAS_COUNT_RD +MBOX7C1 CAS_COUNT_WR + + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Memory read bandwidth [MBytes/s] 1.0E-06*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX6C0+MBOX7C0)*64.0/time +Memory read data volume [GBytes] 1.0E-09*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX6C0+MBOX7C0)*64.0 +Memory write bandwidth [MBytes/s] 1.0E-06*(MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1+MBOX6C1+MBOX7C1)*64.0/time +Memory write data volume [GBytes] 1.0E-09*(MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1+MBOX6C1+MBOX7C1)*64.0 +Memory bandwidth [MBytes/s] 1.0E-06*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX6C0+MBOX7C0+MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1+MBOX6C1+MBOX7C1)*64.0/time +Memory data volume [GBytes] 1.0E-09*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX6C0+MBOX7C0+MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1+MBOX6C1+MBOX7C1)*64.0 + +LONG +Formulas: +Memory read bandwidth [MBytes/s] = 1.0E-06*(SUM(MBOXxC0))*64.0/runtime +Memory read data volume [GBytes] = 1.0E-09*(SUM(MBOXxC0))*64.0 +Memory write bandwidth [MBytes/s] = 1.0E-06*(SUM(MBOXxC1))*64.0/runtime +Memory write data volume [GBytes] = 1.0E-09*(SUM(MBOXxC1))*64.0 +Memory bandwidth [MBytes/s] = 1.0E-06*(SUM(MBOXxC0)+SUM(MBOXxC1))*64.0/runtime +Memory data volume [GBytes] = 1.0E-09*(SUM(MBOXxC0)+SUM(MBOXxC1))*64.0 +- +Profiling group to measure memory bandwidth drawn by all cores of a socket. +Since this group is based on Uncore events it is only possible to measure on a +per socket base. Some of the counters may not be available on your system. +Also outputs total data volume transferred from main memory. +The same metrics are provided by the HA group. + diff --git a/collectors/likwid/groups/broadwellEP/MEM_DP.txt b/collectors/likwid/groups/broadwellEP/MEM_DP.txt new file mode 100644 index 0000000..6078d57 --- /dev/null +++ b/collectors/likwid/groups/broadwellEP/MEM_DP.txt @@ -0,0 +1,73 @@ +SHORT Overview of arithmetic and main memory performance + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PWR0 PWR_PKG_ENERGY +PWR3 PWR_DRAM_ENERGY +PMC0 FP_ARITH_INST_RETIRED_128B_PACKED_DOUBLE +PMC1 FP_ARITH_INST_RETIRED_SCALAR_DOUBLE +PMC2 FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE +MBOX0C0 CAS_COUNT_RD +MBOX0C1 CAS_COUNT_WR +MBOX1C0 CAS_COUNT_RD +MBOX1C1 CAS_COUNT_WR +MBOX2C0 CAS_COUNT_RD +MBOX2C1 CAS_COUNT_WR +MBOX3C0 CAS_COUNT_RD +MBOX3C1 CAS_COUNT_WR +MBOX4C0 CAS_COUNT_RD +MBOX4C1 CAS_COUNT_WR +MBOX5C0 CAS_COUNT_RD +MBOX5C1 CAS_COUNT_WR +MBOX6C0 CAS_COUNT_RD +MBOX6C1 CAS_COUNT_WR +MBOX7C0 CAS_COUNT_RD +MBOX7C1 CAS_COUNT_WR + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Energy [J] PWR0 +Power [W] PWR0/time +Energy DRAM [J] PWR3 +Power DRAM [W] PWR3/time +MFLOP/s 1.0E-06*(PMC0*2.0+PMC1+PMC2*4.0)/time +AVX [MFLOP/s] 1.0E-06*(PMC2*4.0)/time +Packed [MUOPS/s] 1.0E-06*(PMC0+PMC2)/time +Scalar [MUOPS/s] 1.0E-06*PMC1/time +Memory read bandwidth [MBytes/s] 1.0E-06*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX6C0+MBOX7C0)*64.0/time +Memory read data volume [GBytes] 1.0E-09*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX6C0+MBOX7C0)*64.0 +Memory write bandwidth [MBytes/s] 1.0E-06*(MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1+MBOX6C1+MBOX7C1)*64.0/time +Memory write data volume [GBytes] 1.0E-09*(MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1+MBOX6C1+MBOX7C1)*64.0 +Memory bandwidth [MBytes/s] 1.0E-06*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX6C0+MBOX7C0+MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1+MBOX6C1+MBOX7C1)*64.0/time +Memory data volume [GBytes] 1.0E-09*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX6C0+MBOX7C0+MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1+MBOX6C1+MBOX7C1)*64.0 +Operational intensity (PMC0*2.0+PMC1+PMC2*4.0)/((MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX6C0+MBOX7C0+MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1+MBOX6C1+MBOX7C1)*64.0) + +LONG +Formulas: +Power [W] = PWR_PKG_ENERGY/runtime +Power DRAM [W] = PWR_DRAM_ENERGY/runtime +MFLOP/s = 1.0E-06*(FP_ARITH_INST_RETIRED_128B_PACKED_DOUBLE*2+FP_ARITH_INST_RETIRED_SCALAR_DOUBLE+FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE*4)/runtime +AVX [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE*4)/runtime +Packed [MUOPS/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_128B_PACKED_DOUBLE+FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE)/runtime +Scalar [MUOPS/s] = 1.0E-06*FP_ARITH_INST_RETIRED_SCALAR_DOUBLE/runtime +Memory read bandwidth [MBytes/s] = 1.0E-06*(SUM(MBOXxC0))*64.0/runtime +Memory read data volume [GBytes] = 1.0E-09*(SUM(MBOXxC0))*64.0 +Memory write bandwidth [MBytes/s] = 1.0E-06*(SUM(MBOXxC1))*64.0/runtime +Memory write data volume [GBytes] = 1.0E-09*(SUM(MBOXxC1))*64.0 +Memory bandwidth [MBytes/s] = 1.0E-06*(SUM(MBOXxC0)+SUM(MBOXxC1))*64.0/runtime +Memory data volume [GBytes] = 1.0E-09*(SUM(MBOXxC0)+SUM(MBOXxC1))*64.0 +Operational intensity = (FP_ARITH_INST_RETIRED_128B_PACKED_DOUBLE*2+FP_ARITH_INST_RETIRED_SCALAR_DOUBLE+FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE*4)/(SUM(MBOXxC0)+SUM(MBOXxC1))*64.0) +-- +Profiling group to measure memory bandwidth drawn by all cores of a socket. +Since this group is based on Uncore events it is only possible to measure on +a per socket base. Also outputs total data volume transferred from main memory. +SSE scalar and packed double precision FLOP rates. Also reports on packed AVX +32b instructions. +The operational intensity is calculated using the FP values of the cores and the +memory data volume of the whole socket. The actual operational intensity for +multiple CPUs can be found in the statistics table in the Sum column. diff --git a/collectors/likwid/groups/broadwellEP/MEM_SP.txt b/collectors/likwid/groups/broadwellEP/MEM_SP.txt new file mode 100644 index 0000000..d18d2ab --- /dev/null +++ b/collectors/likwid/groups/broadwellEP/MEM_SP.txt @@ -0,0 +1,73 @@ +SHORT Overview of arithmetic and main memory performance + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PWR0 PWR_PKG_ENERGY +PWR3 PWR_DRAM_ENERGY +PMC0 FP_ARITH_INST_RETIRED_128B_PACKED_SINGLE +PMC1 FP_ARITH_INST_RETIRED_SCALAR_SINGLE +PMC2 FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE +MBOX0C0 CAS_COUNT_RD +MBOX0C1 CAS_COUNT_WR +MBOX1C0 CAS_COUNT_RD +MBOX1C1 CAS_COUNT_WR +MBOX2C0 CAS_COUNT_RD +MBOX2C1 CAS_COUNT_WR +MBOX3C0 CAS_COUNT_RD +MBOX3C1 CAS_COUNT_WR +MBOX4C0 CAS_COUNT_RD +MBOX4C1 CAS_COUNT_WR +MBOX5C0 CAS_COUNT_RD +MBOX5C1 CAS_COUNT_WR +MBOX6C0 CAS_COUNT_RD +MBOX6C1 CAS_COUNT_WR +MBOX7C0 CAS_COUNT_RD +MBOX7C1 CAS_COUNT_WR + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Energy [J] PWR0 +Power [W] PWR0/time +Energy DRAM [J] PWR3 +Power DRAM [W] PWR3/time +MFLOP/s 1.0E-06*(PMC0*4.0+PMC1+PMC2*8.0)/time +AVX [MFLOP/s] 1.0E-06*(PMC2*8.0)/time +Packed [MUOPS/s] 1.0E-06*(PMC0+PMC2)/time +Scalar [MUOPS/s] 1.0E-06*PMC1/time +Memory read bandwidth [MBytes/s] 1.0E-06*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX6C0+MBOX7C0)*64.0/time +Memory read data volume [GBytes] 1.0E-09*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX6C0+MBOX7C0)*64.0 +Memory write bandwidth [MBytes/s] 1.0E-06*(MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1+MBOX6C1+MBOX7C1)*64.0/time +Memory write data volume [GBytes] 1.0E-09*(MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1+MBOX6C1+MBOX7C1)*64.0 +Memory bandwidth [MBytes/s] 1.0E-06*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX6C0+MBOX7C0+MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1+MBOX6C1+MBOX7C1)*64.0/time +Memory data volume [GBytes] 1.0E-09*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX6C0+MBOX7C0+MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1+MBOX6C1+MBOX7C1)*64.0 +Operational intensity (PMC0*4.0+PMC1+PMC2*8.0)/((MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX6C0+MBOX7C0+MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1+MBOX6C1+MBOX7C1)*64.0) + +LONG +Formulas: +Power [W] = PWR_PKG_ENERGY/runtime +Power DRAM [W] = PWR_DRAM_ENERGY/runtime +MFLOP/s = 1.0E-06*(FP_ARITH_INST_RETIRED_128B_PACKED_SINGLE*4+FP_ARITH_INST_RETIRED_SCALAR_SINGLE+FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE*8)/runtime +AVX [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE*8)/runtime +Packed [MUOPS/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_128B_PACKED_SINGLE+FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE)/runtime +Scalar [MUOPS/s] = 1.0E-06*FP_ARITH_INST_RETIRED_SCALAR_SINGLE/runtime +Memory read bandwidth [MBytes/s] = 1.0E-06*(SUM(MBOXxC0))*64.0/runtime +Memory read data volume [GBytes] = 1.0E-09*(SUM(MBOXxC0))*64.0 +Memory write bandwidth [MBytes/s] = 1.0E-06*(SUM(MBOXxC1))*64.0/runtime +Memory write data volume [GBytes] = 1.0E-09*(SUM(MBOXxC1))*64.0 +Memory bandwidth [MBytes/s] = 1.0E-06*(SUM(MBOXxC0)+SUM(MBOXxC1))*64.0/runtime +Memory data volume [GBytes] = 1.0E-09*(SUM(MBOXxC0)+SUM(MBOXxC1))*64.0 +Operational intensity = (FP_ARITH_INST_RETIRED_128B_PACKED_SINGLE*4+FP_ARITH_INST_RETIRED_SCALAR_SINGLE+FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE*8)/(SUM(MBOXxC0)+SUM(MBOXxC1))*64.0) +-- +Profiling group to measure memory bandwidth drawn by all cores of a socket. +Since this group is based on Uncore events it is only possible to measure on +a per socket base. Also outputs total data volume transferred from main memory. +SSE scalar and packed single precision FLOP rates. Also reports on packed AVX +32b instructions. +The operational intensity is calculated using the FP values of the cores and the +memory data volume of the whole socket. The actual operational intensity for +multiple CPUs can be found in the statistics table in the Sum column. diff --git a/collectors/likwid/groups/broadwellEP/NUMA.txt b/collectors/likwid/groups/broadwellEP/NUMA.txt new file mode 100644 index 0000000..5b30e25 --- /dev/null +++ b/collectors/likwid/groups/broadwellEP/NUMA.txt @@ -0,0 +1,41 @@ +SHORT Local and remote data transfers + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +BBOX0C0 REQUESTS_READS_LOCAL +BBOX1C0 REQUESTS_READS_LOCAL +BBOX0C1 REQUESTS_READS_REMOTE +BBOX1C1 REQUESTS_READS_REMOTE +BBOX0C2 REQUESTS_WRITES_LOCAL +BBOX1C2 REQUESTS_WRITES_LOCAL +BBOX0C3 REQUESTS_WRITES_REMOTE +BBOX1C3 REQUESTS_WRITES_REMOTE + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Local bandwidth [MByte/s] 1.E-06*((BBOX0C0+BBOX1C0+BBOX0C2+BBOX1C2)*64)/time +Local data volume [GByte] 1.E-09*(BBOX0C0+BBOX1C0+BBOX0C2+BBOX1C2)*64 +Remote bandwidth [MByte/s] 1.E-06*((BBOX0C1+BBOX1C1+BBOX0C3+BBOX1C3)*64)/time +Remote data volume [GByte] 1.E-09*(BBOX0C1+BBOX1C1+BBOX0C3+BBOX1C3)*64 +Total bandwidth [MByte/s] 1.E-06*((BBOX0C0+BBOX1C0+BBOX0C2+BBOX1C2+BBOX0C1+BBOX1C1+BBOX0C3+BBOX1C3)*64)/time +Total data volume [GByte] 1.E-09*(BBOX0C0+BBOX1C0+BBOX0C2+BBOX1C2+BBOX0C1+BBOX1C1+BBOX0C3+BBOX1C3)*64 + + +LONG +Formulas: +CPI = CPU_CLK_UNHALTED_CORE/INSTR_RETIRED_ANY +Local bandwidth [MByte/s] = 1.E-06*((SUM(REQUESTS_READS_LOCAL)+SUM(REQUESTS_WRITES_LOCAL))*64)/time +Local data volume [GByte] = 1.E-09*(SUM(REQUESTS_READS_LOCAL)+SUM(REQUESTS_WRITES_LOCAL))*64 +Remote bandwidth [MByte/s] = 1.E-06*((SUM(REQUESTS_READS_REMOTE)+SUM(REQUESTS_WRITES_REMOTE))*64)/time +Remote data volume [GByte] = 1.E-09*(SUM(REQUESTS_READS_REMOTE)+SUM(REQUESTS_WRITES_REMOTE))*64 +Total bandwidth [MByte/s] = 1.E-06*((SUM(REQUESTS_READS_LOCAL)+SUM(REQUESTS_WRITES_LOCAL)+SUM(REQUESTS_READS_REMOTE)+SUM(REQUESTS_WRITES_REMOTE))*64)/time +Total data volume [GByte] = 1.E-09*(SUM(REQUESTS_READS_LOCAL)+SUM(REQUESTS_WRITES_LOCAL)+SUM(REQUESTS_READS_REMOTE)+SUM(REQUESTS_WRITES_REMOTE))*64 +-- +This performance group measures the data traffic of CPU sockets to local and remote +CPU sockets. It uses the Home Agent for calculation. This may include also data from +other sources than the memory controllers. diff --git a/collectors/likwid/groups/broadwellEP/PORT_USAGE.txt b/collectors/likwid/groups/broadwellEP/PORT_USAGE.txt new file mode 100644 index 0000000..298df1d --- /dev/null +++ b/collectors/likwid/groups/broadwellEP/PORT_USAGE.txt @@ -0,0 +1,50 @@ +SHORT Execution port utilization + +REQUIRE_NOHT + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 UOPS_EXECUTED_PORT_PORT_0 +PMC1 UOPS_EXECUTED_PORT_PORT_1 +PMC2 UOPS_EXECUTED_PORT_PORT_2 +PMC3 UOPS_EXECUTED_PORT_PORT_3 +PMC4 UOPS_EXECUTED_PORT_PORT_4 +PMC5 UOPS_EXECUTED_PORT_PORT_5 +PMC6 UOPS_EXECUTED_PORT_PORT_6 +PMC7 UOPS_EXECUTED_PORT_PORT_7 + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Port0 usage ratio PMC0/(PMC0+PMC1+PMC2+PMC3+PMC4+PMC5+PMC6+PMC7) +Port1 usage ratio PMC1/(PMC0+PMC1+PMC2+PMC3+PMC4+PMC5+PMC6+PMC7) +Port2 usage ratio PMC2/(PMC0+PMC1+PMC2+PMC3+PMC4+PMC5+PMC6+PMC7) +Port3 usage ratio PMC3/(PMC0+PMC1+PMC2+PMC3+PMC4+PMC5+PMC6+PMC7) +Port4 usage ratio PMC4/(PMC0+PMC1+PMC2+PMC3+PMC4+PMC5+PMC6+PMC7) +Port5 usage ratio PMC5/(PMC0+PMC1+PMC2+PMC3+PMC4+PMC5+PMC6+PMC7) +Port6 usage ratio PMC6/(PMC0+PMC1+PMC2+PMC3+PMC4+PMC5+PMC6+PMC7) +Port7 usage ratio PMC7/(PMC0+PMC1+PMC2+PMC3+PMC4+PMC5+PMC6+PMC7) + +LONG +Formulas: +Port0 usage ratio = UOPS_EXECUTED_PORT_PORT_0/SUM(UOPS_EXECUTED_PORT_PORT_*) +Port1 usage ratio = UOPS_EXECUTED_PORT_PORT_1/SUM(UOPS_EXECUTED_PORT_PORT_*) +Port2 usage ratio = UOPS_EXECUTED_PORT_PORT_2/SUM(UOPS_EXECUTED_PORT_PORT_*) +Port3 usage ratio = UOPS_EXECUTED_PORT_PORT_3/SUM(UOPS_EXECUTED_PORT_PORT_*) +Port4 usage ratio = UOPS_EXECUTED_PORT_PORT_4/SUM(UOPS_EXECUTED_PORT_PORT_*) +Port5 usage ratio = UOPS_EXECUTED_PORT_PORT_5/SUM(UOPS_EXECUTED_PORT_PORT_*) +Port6 usage ratio = UOPS_EXECUTED_PORT_PORT_6/SUM(UOPS_EXECUTED_PORT_PORT_*) +Port7 usage ratio = UOPS_EXECUTED_PORT_PORT_7/SUM(UOPS_EXECUTED_PORT_PORT_*) +- +This group measures the execution port utilization in a CPU core. The group can +only be measured when HyperThreading is disabled because only then each CPU core +can program eight counters. +Please be aware that the counters PMC4-7 are broken on Intel Broadwell. They +don't increment if either user- or kernel-level filtering is applied. User-level +filtering is default in LIKWID, hence kernel-level filtering is added +automatically for PMC4-7. The returned counts can be much higher. diff --git a/collectors/likwid/groups/broadwellEP/QPI.txt b/collectors/likwid/groups/broadwellEP/QPI.txt new file mode 100644 index 0000000..8594706 --- /dev/null +++ b/collectors/likwid/groups/broadwellEP/QPI.txt @@ -0,0 +1,49 @@ +SHORT QPI Link Layer data + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +QBOX0C0 RXL_FLITS_G0_DATA +QBOX1C0 RXL_FLITS_G0_DATA +QBOX0C1 RXL_FLITS_G0_NON_DATA +QBOX1C1 RXL_FLITS_G0_NON_DATA +QBOX0C2 TXL_FLITS_G0_DATA +QBOX1C2 TXL_FLITS_G0_DATA +QBOX0C3 TXL_FLITS_G0_NON_DATA +QBOX1C3 TXL_FLITS_G0_NON_DATA + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +QPI send data volume [GByte] 1.E-09*(QBOX0C2+QBOX1C2)*8 +QPI send data bandwidth [MByte/s] 1.E-06*(QBOX0C2+QBOX1C2)*8/time +QPI send link volume [GByte] 1.E-09*(QBOX0C2+QBOX1C2+QBOX0C3+QBOX1C3)*8 +QPI send link bandwidth [MByte/s] 1.E-06*(QBOX0C2+QBOX1C2+QBOX0C3+QBOX1C3)*8/time +QPI receive data volume [GByte] 1.E-09*(QBOX0C0+QBOX1C0)*8 +QPI receive data bandwidth [MByte/s] 1.E-06*(QBOX0C0+QBOX1C0)*8/time +QPI receive link volume [GByte] 1.E-09*(QBOX0C0+QBOX1C0+QBOX0C1+QBOX1C1)*8 +QPI receive link bandwidth [MByte/s] 1.E-06*(QBOX0C0+QBOX1C0+QBOX0C1+QBOX1C1)*8/time +QPI total transfer volume [GByte] 1.E-09*(QBOX0C0+QBOX1C0+QBOX0C2+QBOX1C2+QBOX0C1+QBOX1C1+QBOX0C3+QBOX1C3)*8 +QPI total bandwidth [MByte/s] 1.E-06*(QBOX0C0+QBOX1C0+QBOX0C2+QBOX1C2+QBOX0C1+QBOX1C1+QBOX0C3+QBOX1C3)*8/time + +LONG +Formulas: +QPI send data volume [GByte] = 1.E-09*(sum(TXL_FLITS_G0_DATA)*8) +QPI send data bandwidth [MByte/s] = 1.E-06*(sum(TXL_FLITS_G0_DATA)*8)/runtime +QPI send link volume [GByte] = 1.E-09*((sum(TXL_FLITS_G0_DATA)+sum(TXL_FLITS_G0_NON_DATA))*8) +QPI send link bandwidth [MByte/s] = 1.E-06*((sum(TXL_FLITS_G0_DATA)+sum(TXL_FLITS_G0_NON_DATA))*8)/runtime +QPI receive data volume [GByte] = 1.E-09*(sum(RXL_FLITS_G0_DATA)*8) +QPI receive data bandwidth [MByte/s] = 1.E-06*(sum(RXL_FLITS_G0_DATA)*8)/runtime +QPI receive link volume [GByte] = 1.E-09*((sum(RXL_FLITS_G0_DATA)+sum(RXL_FLITS_G0_NON_DATA))*8) +QPI receive link bandwidth [MByte/s] = 1.E-06*((sum(RXL_FLITS_G0_DATA)+sum(RXL_FLITS_G0_NON_DATA))*8)/runtime +QPI total transfer volume [GByte] = 1.E-09*(sum(TXL_FLITS_G0_DATA)+sum(TXL_FLITS_G0_NON_DATA)+sum(RXL_FLITS_G0_DATA)+sum(RXL_FLITS_G0_NON_DATA))*8 +QPI total bandwidth [MByte/s] = 1.E-06*(sum(TXL_FLITS_G0_DATA)+sum(TXL_FLITS_G0_NON_DATA)+sum(RXL_FLITS_G0_DATA)+sum(RXL_FLITS_G0_NON_DATA))*8/time +-- +The Intel QPI Link Layer is responsible for packetizing requests from the caching agent (CBOXes) +on the way out to the system interface. For Broadwell EP systems, the Link Layer and the +Ring interface is separated. The QPI link volume contains header, data and trailer while the +QPI data volume counts only the data flits. diff --git a/collectors/likwid/groups/broadwellEP/TLB_DATA.txt b/collectors/likwid/groups/broadwellEP/TLB_DATA.txt new file mode 100644 index 0000000..54f5e05 --- /dev/null +++ b/collectors/likwid/groups/broadwellEP/TLB_DATA.txt @@ -0,0 +1,35 @@ +SHORT L2 data TLB miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 DTLB_LOAD_MISSES_CAUSES_A_WALK +PMC1 DTLB_STORE_MISSES_CAUSES_A_WALK +PMC2 DTLB_LOAD_MISSES_WALK_DURATION +PMC3 DTLB_STORE_MISSES_WALK_DURATION + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L1 DTLB load misses PMC0 +L1 DTLB load miss rate PMC0/FIXC0 +L1 DTLB load miss duration PMC2 +L1 DTLB store misses PMC1 +L1 DTLB store miss rate PMC1/FIXC0 +L1 DTLB store miss duration PMC3 + +LONG +Formulas: +L1 DTLB load misses = DTLB_LOAD_MISSES_CAUSES_A_WALK +L1 DTLB load miss rate = DTLB_LOAD_MISSES_CAUSES_A_WALK / INSTR_RETIRED_ANY +L1 DTLB load miss duration = DTLB_LOAD_MISSES_WALK_DURATION +L1 DTLB store misses = DTLB_STORE_MISSES_CAUSES_A_WALK +L1 DTLB store miss rate = DTLB_STORE_MISSES_CAUSES_A_WALK / INSTR_RETIRED_ANY +L1 DTLB store miss duration = DTLB_STORE_MISSES_WALK_DURATION +- +The DTLB load and store miss rates gives a measure how often a TLB miss occurred +per instruction. The duration measures the time in cycles how long a walk did take. + diff --git a/collectors/likwid/groups/broadwellEP/TLB_INSTR.txt b/collectors/likwid/groups/broadwellEP/TLB_INSTR.txt new file mode 100644 index 0000000..647748f --- /dev/null +++ b/collectors/likwid/groups/broadwellEP/TLB_INSTR.txt @@ -0,0 +1,28 @@ +SHORT L1 Instruction TLB miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 ITLB_MISSES_CAUSES_A_WALK +PMC1 ITLB_MISSES_WALK_DURATION + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L1 ITLB misses PMC0 +L1 ITLB miss rate PMC0/FIXC0 +L1 ITLB miss duration PMC1 + + +LONG +Formulas: +L1 ITLB misses = ITLB_MISSES_CAUSES_A_WALK +L1 ITLB miss rate = ITLB_MISSES_CAUSES_A_WALK / INSTR_RETIRED_ANY +L1 ITLB miss duration = ITLB_MISSES_WALK_DURATION +- +The ITLB miss rates gives a measure how often a TLB miss occurred +per instruction. The duration measures the time in cycles how long a walk did take. + diff --git a/collectors/likwid/groups/broadwellEP/TMA.txt b/collectors/likwid/groups/broadwellEP/TMA.txt new file mode 100644 index 0000000..afb4126 --- /dev/null +++ b/collectors/likwid/groups/broadwellEP/TMA.txt @@ -0,0 +1,48 @@ +SHORT Top down cycle allocation + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 UOPS_ISSUED_ANY +PMC1 UOPS_RETIRED_RETIRE_SLOTS +PMC2 IDQ_UOPS_NOT_DELIVERED_CORE +PMC3 INT_MISC_RECOVERY_CYCLES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +IPC FIXC0/FIXC1 +Total Slots 4*FIXC1 +Slots Retired PMC1 +Fetch Bubbles PMC2 +Recovery Bubbles 4*PMC3 +Front End [%] PMC2/(4*FIXC1)*100 +Speculation [%] (PMC0-PMC1+(4*PMC3))/(4*FIXC1)*100 +Retiring [%] PMC1/(4*FIXC1)*100 +Back End [%] (1-((PMC2+PMC0+(4*PMC3))/(4*FIXC1)))*100 + +LONG +Formulas: +Total Slots = 4*CPU_CLK_UNHALTED_CORE +Slots Retired = UOPS_RETIRED_RETIRE_SLOTS +Fetch Bubbles = IDQ_UOPS_NOT_DELIVERED_CORE +Recovery Bubbles = 4*INT_MISC_RECOVERY_CYCLES +Front End [%] = IDQ_UOPS_NOT_DELIVERED_CORE/(4*CPU_CLK_UNHALTED_CORE)*100 +Speculation [%] = (UOPS_ISSUED_ANY-UOPS_RETIRED_RETIRE_SLOTS+(4*INT_MISC_RECOVERY_CYCLES))/(4*CPU_CLK_UNHALTED_CORE)*100 +Retiring [%] = UOPS_RETIRED_RETIRE_SLOTS/(4*CPU_CLK_UNHALTED_CORE)*100 +Back End [%] = (1-((IDQ_UOPS_NOT_DELIVERED_CORE+UOPS_ISSUED_ANY+(4*INT_MISC_RECOVERY_CYCLES))/(4*CPU_CLK_UNHALTED_CORE)))*100 +-- +This performance group measures cycles to determine percentage of time spent in +front end, back end, retiring and speculation. These metrics are published and +verified by Intel. Further information: +Webpage describing Top-Down Method and its usage in Intel vTune: +https://software.intel.com/en-us/vtune-amplifier-help-tuning-applications-using-a-top-down-microarchitecture-analysis-method +Paper by Yasin Ahmad: +https://sites.google.com/site/analysismethods/yasin-pubs/TopDown-Yasin-ISPASS14.pdf?attredirects=0 +Slides by Yasin Ahmad: +http://www.cs.technion.ac.il/~erangi/TMA_using_Linux_perf__Ahmad_Yasin.pdf +The performance group was originally published here: +http://perf.mvermeulen.com/2018/04/14/top-down-performance-counter-analysis-part-1-likwid/ diff --git a/collectors/likwid/groups/broadwellEP/UOPS.txt b/collectors/likwid/groups/broadwellEP/UOPS.txt new file mode 100644 index 0000000..e6cc208 --- /dev/null +++ b/collectors/likwid/groups/broadwellEP/UOPS.txt @@ -0,0 +1,35 @@ +SHORT UOPs execution info + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 UOPS_ISSUED_ANY +PMC1 UOPS_EXECUTED_THREAD +PMC2 UOPS_RETIRED_ALL +PMC3 UOPS_ISSUED_FLAGS_MERGE + + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Issued UOPs PMC0 +Merged UOPs PMC3 +Executed UOPs PMC1 +Retired UOPs PMC2 + +LONG +Formulas: +Issued UOPs = UOPS_ISSUED_ANY +Merged UOPs = UOPS_ISSUED_FLAGS_MERGE +Executed UOPs = UOPS_EXECUTED_THREAD +Retired UOPs = UOPS_RETIRED_ALL +- +This group returns information about the instruction pipeline. It measures the +issued, executed and retired uOPs and returns the number of uOPs which were issued +but not executed as well as the number of uOPs which were executed but never retired. +The executed but not retired uOPs commonly come from speculatively executed branches. + diff --git a/collectors/likwid/groups/core2/BRANCH.txt b/collectors/likwid/groups/core2/BRANCH.txt new file mode 100644 index 0000000..3c66c00 --- /dev/null +++ b/collectors/likwid/groups/core2/BRANCH.txt @@ -0,0 +1,30 @@ +SHORT Branch prediction miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 BR_INST_RETIRED_ANY +PMC1 BR_INST_RETIRED_MISPRED + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Branch rate PMC0/FIXC0 +Branch misprediction rate PMC1/FIXC0 +Branch misprediction ratio PMC1/PMC0 +Instructions per branch FIXC0/PMC0 + +LONG +Formulas: +Branch rate = BR_INST_RETIRED_ANY/INSTR_RETIRED_ANY +Branch misprediction rate = BR_INST_RETIRED_MISPRED/INSTR_RETIRED_ANY +Branch misprediction ratio = BR_INST_RETIRED_MISPRED/BR_INST_RETIRED_ANY +Instructions per branch = INSTR_RETIRED_ANY/BR_INST_RETIRED_ANY +- +The rates state how often on average a branch or a mispredicted branch occurred +per instruction retired in total. The branch misprediction ratio sets directly +into relation what ratio of all branch instruction where mispredicted. +Instructions per branch is 1/branch rate. diff --git a/collectors/likwid/groups/core2/CACHE.txt b/collectors/likwid/groups/core2/CACHE.txt new file mode 100644 index 0000000..6eda059 --- /dev/null +++ b/collectors/likwid/groups/core2/CACHE.txt @@ -0,0 +1,34 @@ +SHORT Data cache miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 L1D_REPL +PMC1 L1D_ALL_REF + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +CPI FIXC1/FIXC0 +data cache misses PMC0 +data cache request rate PMC1/FIXC0 +data cache miss rate PMC0/FIXC0 +data cache miss ratio PMC0/PMC1 + +LONG +Formulas: +data cache request rate = L1D_ALL_REF / INSTR_RETIRED_ANY +data cache miss rate = L1D_REPL / INSTR_RETIRED_ANY +data cache miss ratio = L1D_REPL / L1D_ALL_REF +- +This group measures the locality of your data accesses with regard to the +L1 cache. Data cache request rate tells you how data intensive your code is +or how many data accesses you have on average per instruction. +The data cache miss rate gives a measure how often it was necessary to get +cache lines from higher levels of the memory hierarchy. And finally +data cache miss ratio tells you how many of your memory references required +a cache line to be loaded from a higher level. While the# data cache miss rate +might be given by your algorithm you should try to get data cache miss ratio +as low as possible by increasing your cache reuse. + diff --git a/collectors/likwid/groups/core2/CLOCK.txt b/collectors/likwid/groups/core2/CLOCK.txt new file mode 100644 index 0000000..871c4f9 --- /dev/null +++ b/collectors/likwid/groups/core2/CLOCK.txt @@ -0,0 +1,19 @@ +SHORT CPU clock information + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 + +LONG +Formulas: +CPI = CPU_CLK_UNHALTED_CORE / INSTR_RETIRED_ANY +- +Most basic performance group measuring the the clock frequency of the machine. + diff --git a/collectors/likwid/groups/core2/DATA.txt b/collectors/likwid/groups/core2/DATA.txt new file mode 100644 index 0000000..0f5bca5 --- /dev/null +++ b/collectors/likwid/groups/core2/DATA.txt @@ -0,0 +1,22 @@ +SHORT Load to store ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 INST_RETIRED_LOADS +PMC1 INST_RETIRED_STORES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Load to store ratio PMC0/PMC1 + +LONG +Formulas: +Load to store ratio = INST_RETIRED_LOADS/INST_RETIRED_STORES +- +This is a simple metric to determine your load to store ratio. + diff --git a/collectors/likwid/groups/core2/DIVIDE.txt b/collectors/likwid/groups/core2/DIVIDE.txt new file mode 100644 index 0000000..0753b4e --- /dev/null +++ b/collectors/likwid/groups/core2/DIVIDE.txt @@ -0,0 +1,24 @@ +SHORT Divide unit information + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 CYCLES_DIV_BUSY +PMC1 DIV + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Number of divide ops PMC1 +Avg. divide unit usage duration PMC0/PMC1 + +LONG +Formulas: +Number of divide ops = DIV +Avg. divide unit usage duration = CYCLES_DIV_BUSY/DIV +- +This performance group measures the average latency of divide operations diff --git a/collectors/likwid/groups/core2/FLOPS_DP.txt b/collectors/likwid/groups/core2/FLOPS_DP.txt new file mode 100644 index 0000000..e1698ff --- /dev/null +++ b/collectors/likwid/groups/core2/FLOPS_DP.txt @@ -0,0 +1,29 @@ +SHORT Double Precision MFLOP/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 SIMD_COMP_INST_RETIRED_PACKED_DOUBLE +PMC1 SIMD_COMP_INST_RETIRED_SCALAR_DOUBLE + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +CPI FIXC1/FIXC0 +DP [MFLOP/s] 1.0E-06*(PMC0*2.0+PMC1)/time +Packed [MUOPS/s] 1.0E-06*PMC0/time +Scalar [MUOPS/s] 1.0E-06*PMC1/time +Vectorization ratio 100*PMC0/PMC1 + +LONG +Formulas: +DP [MFLOP/s] = 1.0E-06*(SIMD_COMP_INST_RETIRED_PACKED_DOUBLE*2+SIMD_COMP_INST_RETIRED_SCALAR_DOUBLE)/time +Packed [MUOPS/s] = 1.0E-06*SIMD_COMP_INST_RETIRED_PACKED_DOUBLE/runtime +Scalar [MUOPS/s] = 1.0E-06*SIMD_COMP_INST_RETIRED_SCALAR_DOUBLE/runtime +Vectorization ratio = 100*SIMD_COMP_INST_RETIRED_PACKED_DOUBLE/SIMD_COMP_INST_RETIRED_SCALAR_DOUBLE +- +Profiling group to measure double SSE FLOPs. Don't forget that your code might also execute X87 FLOPs. +On the number of SIMD_COMP_INST_RETIRED_PACKED_DOUBLE you can see how well your code was vectorized. + + diff --git a/collectors/likwid/groups/core2/FLOPS_SP.txt b/collectors/likwid/groups/core2/FLOPS_SP.txt new file mode 100644 index 0000000..a2c842c --- /dev/null +++ b/collectors/likwid/groups/core2/FLOPS_SP.txt @@ -0,0 +1,29 @@ +SHORT Single Precision MFLOP/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 SIMD_COMP_INST_RETIRED_PACKED_SINGLE +PMC1 SIMD_COMP_INST_RETIRED_SCALAR_SINGLE + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +CPI FIXC1/FIXC0 +SP [MFLOP/s] 1.0E-06*(PMC0*4.0+PMC1)/time +Packed [MUOPS/s] 1.0E-06*PMC0/time +Scalar [MUOPS/s] 1.0E-06*PMC1/time +Vectorization ratio 100*PMC0/PMC1 + +LONG +Formulas: +SP [MFLOP/s] = 1.0E-06*(SIMD_COMP_INST_RETIRED_PACKED_SINGLE*4+SIMD_COMP_INST_RETIRED_SCALAR_SINGLE)/time +Packed [MUOPS/s] = 1.0E-06*SIMD_COMP_INST_RETIRED_PACKED_SINGLE/runtime +Scalar [MUOPS/s] = 1.0E-06*SIMD_COMP_INST_RETIRED_SCALAR_SINGLE/runtime +Vectorization ratio [%] = 100*SIMD_COMP_INST_RETIRED_PACKED_SINGLE/SIMD_COMP_INST_RETIRED_SCALAR_SINGLE +- +Profiling group to measure single precision SSE FLOPs. Don't forget that your code might also execute X87 FLOPs. +On the number of SIMD_COMP_INST_RETIRED_PACKED_SINGLE you can see how well your code was vectorized. + + diff --git a/collectors/likwid/groups/core2/FLOPS_X87.txt b/collectors/likwid/groups/core2/FLOPS_X87.txt new file mode 100644 index 0000000..46309e4 --- /dev/null +++ b/collectors/likwid/groups/core2/FLOPS_X87.txt @@ -0,0 +1,21 @@ +SHORT X87 MFLOP/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 X87_OPS_RETIRED_ANY + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +CPI FIXC1/FIXC0 +X87 [MFLOP/s] 1.0E-06*PMC0/time + +LONG +Formulas: +X87 [MFLOP/s] = 1.0E-06*X87_OPS_RETIRED_ANY/time +- +Profiling group to measure X87 FLOPs. Note that also non computational operations +are measured by this event. + diff --git a/collectors/likwid/groups/core2/L2.txt b/collectors/likwid/groups/core2/L2.txt new file mode 100644 index 0000000..d8cbe0d --- /dev/null +++ b/collectors/likwid/groups/core2/L2.txt @@ -0,0 +1,35 @@ +SHORT L2 cache bandwidth in MBytes/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 L1D_REPL +PMC1 L1D_M_EVICT + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +CPI FIXC1/FIXC0 +L2D load bandwidth [MBytes/s] 1.0E-06*PMC0*64.0/time +L2D load data volume [GBytes] 1.0E-09*PMC0*64.0 +L2D evict bandwidth [MBytes/s] 1.0E-06*PMC1*64.0/time +L2D evict data volume [GBytes] 1.0E-09*PMC1*64.0 +L2 bandwidth [MBytes/s] 1.0E-06*(PMC0+PMC1)*64.0/time +L2 data volume [GBytes] 1.0E-09*(PMC0+PMC1)*64.0 + +LONG +Formulas: +L2D load bandwidth [MBytes/s] = 1.0E-06*L1D_REPL*64.0/time +L2D load data volume [GBytes] = 1.0E-09*L1D_REPL*64.0 +L2D evict bandwidth [MBytes/s] = 1.0E-06*L1D_M_EVICT*64.0/time +L2D evict data volume [GBytes] = 1.0E-09*L1D_M_EVICT*64.0 +L2 bandwidth [MBytes/s] = 1.0E-06*(L1D_REPL+L1D_M_EVICT)*64/time +L2 data volume [GBytes] = 1.0E-09*(L1D_REPL+L1D_M_EVICT)*64.0 +- +Profiling group to measure L2 cache bandwidth. The bandwidth is +computed by the number of cache line allocated in the L1 and the +number of modified cache lines evicted from the L1. +Note that this bandwidth also includes data transfers due to a +write allocate load on a store miss in L1. + diff --git a/collectors/likwid/groups/core2/L2CACHE.txt b/collectors/likwid/groups/core2/L2CACHE.txt new file mode 100644 index 0000000..d3b8776 --- /dev/null +++ b/collectors/likwid/groups/core2/L2CACHE.txt @@ -0,0 +1,34 @@ +SHORT L2 cache miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 L2_RQSTS_THIS_CORE_ALL_MESI +PMC1 L2_RQSTS_SELF_I_STATE + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L2 request rate PMC0/FIXC0 +L2 miss rate PMC1/FIXC0 +L2 miss ratio PMC1/PMC0 + +LONG +Formulas: +L2 request rate = L2_RQSTS_THIS_CORE_ALL_MESI / INSTR_RETIRED_ANY +L2 miss rate = L2_RQSTS_SELF_I_STATE / INSTR_RETIRED_ANY +L2 miss ratio = L2_RQSTS_SELF_I_STATE / L2_RQSTS_THIS_CORE_ALL_MESI +- +This group measures the locality of your data accesses with regard to the +L2 cache. L2 request rate tells you how data intensive your code is +or how many data accesses you have on average per instruction. +The L2 miss rate gives a measure how often it was necessary to get +cache lines from memory. And finally L2 miss ratio tells you how many of your +memory references required a cache line to be loaded from a higher level. +While the# data cache miss rate might be given by your algorithm you should +try to get data cache miss ratio as low as possible by increasing your cache reuse. + + diff --git a/collectors/likwid/groups/core2/MEM.txt b/collectors/likwid/groups/core2/MEM.txt new file mode 100644 index 0000000..f6522ba --- /dev/null +++ b/collectors/likwid/groups/core2/MEM.txt @@ -0,0 +1,23 @@ +SHORT Main memory bandwidth in MBytes/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 BUS_TRANS_MEM_THIS_CORE_THIS_A +PMC1 BUS_TRANS_WB_THIS_CORE_ALL_A + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Memory bandwidth [MBytes/s] 1.0E-06*(PMC0+PMC1)*64.0/time +Memory data volume [GBytes] 1.0E-09*(PMC0+PMC1)*64.0 + +LONG +Formulas: +Memory bandwidth [MBytes/s] = 1.0E-06*BUS_TRANS_MEM_THIS_CORE_THIS_A*64/time +Memory data volume [GBytes] = 1.0E-09*BUS_TRANS_MEM_THIS_CORE_THIS_A*64.0 +- +Profiling group to measure memory bandwidth drawn by this core. diff --git a/collectors/likwid/groups/core2/TLB.txt b/collectors/likwid/groups/core2/TLB.txt new file mode 100644 index 0000000..a46cc4b --- /dev/null +++ b/collectors/likwid/groups/core2/TLB.txt @@ -0,0 +1,29 @@ +SHORT TLB miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 DTLB_MISSES_ANY +PMC1 L1D_ALL_REF + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +CPI FIXC1/FIXC0 +L1 DTLB request rate PMC1/FIXC0 +DTLB miss rate PMC0/FIXC0 +L1 DTLB miss ratio PMC0/PMC1 + +LONG +Formulas: +L1 DTLB request rate = L1D_ALL_REF / INSTR_RETIRED_ANY +DTLB miss rate = DTLB_MISSES_ANY / INSTR_RETIRED_ANY +L1 DTLB miss ratio = DTLB_MISSES_ANY / L1D_ALL_REF +- +L1 DTLB request rate tells you how data intensive your code is +or how many data accesses you have on average per instruction. +The DTLB miss rate gives a measure how often a TLB miss occurred +per instruction. And finally L1 DTLB miss ratio tells you how many +of your memory references required caused a TLB miss on average. + diff --git a/collectors/likwid/groups/core2/UOPS.txt b/collectors/likwid/groups/core2/UOPS.txt new file mode 100644 index 0000000..5d816d8 --- /dev/null +++ b/collectors/likwid/groups/core2/UOPS.txt @@ -0,0 +1,26 @@ +SHORT UOPs execution info + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 RS_UOPS_DISPATCHED_ALL +PMC1 UOPS_RETIRED_ANY + + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Executed UOPs PMC0 +Retired UOPs PMC1 + +LONG +Formulas: +Executed UOPs = RS_UOPS_DISPATCHED_ALL +Retired UOPs = UOPS_RETIRED_ANY +- +Performance group measures the executed and retired micro ops. The difference +between executed and retired uOPs are the speculatively executed uOPs. diff --git a/collectors/likwid/groups/core2/UOPS_RETIRE.txt b/collectors/likwid/groups/core2/UOPS_RETIRE.txt new file mode 100644 index 0000000..be0bf73 --- /dev/null +++ b/collectors/likwid/groups/core2/UOPS_RETIRE.txt @@ -0,0 +1,25 @@ +SHORT UOPs retirement + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 UOPS_RETIRED_USED_CYCLES +PMC1 UOPS_RETIRED_STALL_CYCLES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Used cycles ratio PMC0/FIXC1 +Unused cycles ratio PMC1/FIXC1 + + +LONG +Formulas: +Used cycles ratio = UOPS_RETIRED_USED_CYCLES/CPU_CLK_UNHALTED_CORE +Unused cycles ratio = UOPS_RETIRED_STALL_CYCLES/CPU_CLK_UNHALTED_CORE +- +This performance group returns the ratios of used and unused CPU cycles. Here +unused cycles are cycles where no operation is performed due to some stall. diff --git a/collectors/likwid/groups/goldmont/BRANCH.txt b/collectors/likwid/groups/goldmont/BRANCH.txt new file mode 100644 index 0000000..b8d41b2 --- /dev/null +++ b/collectors/likwid/groups/goldmont/BRANCH.txt @@ -0,0 +1,31 @@ +SHORT Branch prediction miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 BR_INST_RETIRED_ALL_BRANCHES +PMC1 BR_MISP_RETIRED_ALL_BRANCHES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Branch rate PMC0/FIXC0 +Branch misprediction rate PMC1/FIXC0 +Branch misprediction ratio PMC1/PMC0 +Instructions per branch FIXC0/PMC0 + +LONG +Formulas: +Branch rate = BR_INST_RETIRED_ALL_BRANCHES/INSTR_RETIRED_ANY +Branch misprediction rate = BR_MISP_RETIRED_ALL_BRANCHES/INSTR_RETIRED_ANY +Branch misprediction ratio = BR_MISP_RETIRED_ALL_BRANCHES/BR_INST_RETIRED_ALL_BRANCHES +Instructions per branch = INSTR_RETIRED_ANY/BR_INST_RETIRED_ALL_BRANCHES +- +The rates state how often on average a branch or a mispredicted branch occurred +per instruction retired in total. The branch misprediction ratio sets directly +into relation what ratio of all branch instruction where mispredicted. +Instructions per branch is 1/branch rate. + diff --git a/collectors/likwid/groups/goldmont/CLOCK.txt b/collectors/likwid/groups/goldmont/CLOCK.txt new file mode 100644 index 0000000..b2174c8 --- /dev/null +++ b/collectors/likwid/groups/goldmont/CLOCK.txt @@ -0,0 +1,23 @@ +SHORT Power and Energy consumption + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PWR0 PWR_PKG_ENERGY + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Energy [J] PWR0 +Power [W] PWR0/time + +LONG +Formulas: +Power = PWR_PKG_ENERGY / time +- +Silvermont implements the new RAPL interface. This interface enables to +monitor the consumed energy on the package (socket) level. + diff --git a/collectors/likwid/groups/goldmont/DATA.txt b/collectors/likwid/groups/goldmont/DATA.txt new file mode 100644 index 0000000..61a915b --- /dev/null +++ b/collectors/likwid/groups/goldmont/DATA.txt @@ -0,0 +1,22 @@ +SHORT Load to store ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 MEM_UOPS_RETIRED_ALL_LOADS +PMC1 MEM_UOPS_RETIRED_ALL_STORES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Load to store ratio PMC0/PMC1 + +LONG +Formulas: +Load to store ratio = MEM_UOPS_RETIRED_ALL_LOADS/MEM_UOPS_RETIRED_ALL_STORES +- +This is a metric to determine your load to store ratio. + diff --git a/collectors/likwid/groups/goldmont/DIVIDE.txt b/collectors/likwid/groups/goldmont/DIVIDE.txt new file mode 100644 index 0000000..9fc6702 --- /dev/null +++ b/collectors/likwid/groups/goldmont/DIVIDE.txt @@ -0,0 +1,24 @@ +SHORT Divide unit information + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 CYCLES_DIV_BUSY_ALL +PMC1 CYCLES_DIV_BUSY_ALL_COUNT + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Number of divide ops PMC1 +Avg. divide unit usage duration PMC0/PMC1 + +LONG +Formulas: +Number of divide ops = CYCLES_DIV_BUSY_ALL_COUNT +Avg. divide unit usage duration = CYCLES_DIV_BUSY_ALL/CYCLES_DIV_BUSY_ALL_COUNT +- +This performance group measures the average latency of divide operations diff --git a/collectors/likwid/groups/goldmont/ENERGY.txt b/collectors/likwid/groups/goldmont/ENERGY.txt new file mode 100644 index 0000000..7770534 --- /dev/null +++ b/collectors/likwid/groups/goldmont/ENERGY.txt @@ -0,0 +1,33 @@ +SHORT Power and Energy consumption + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +TMP0 TEMP_CORE +PWR0 PWR_PKG_ENERGY +PWR1 PWR_PP0_ENERGY +PWR3 PWR_DRAM_ENERGY + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Temperature [C] TMP0 +Energy [J] PWR0 +Power [W] PWR0/time +Energy PP0 [J] PWR1 +Power PP0 [W] PWR1/time +Energy DRAM [J] PWR1 +Power DRAM [W] PWR1/time + +LONG +Formulas: +Power = PWR_PKG_ENERGY / time +Power PP0 = PWR_PP0_ENERGY / time +Power DRAM = PWR_DRAM_ENERGY / time +- +Goldmont implements the new RAPL interface. This interface enables to +monitor the consumed energy on the package (socket) level. + diff --git a/collectors/likwid/groups/goldmont/ICACHE.txt b/collectors/likwid/groups/goldmont/ICACHE.txt new file mode 100644 index 0000000..5f11ad6 --- /dev/null +++ b/collectors/likwid/groups/goldmont/ICACHE.txt @@ -0,0 +1,25 @@ +SHORT Instruction cache miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 ICACHE_ACCESSES +PMC1 ICACHE_MISSES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L1I request rate PMC0/FIXC0 +L1I miss rate PMC1/FIXC0 +L1I miss ratio PMC1/PMC0 + +LONG +Formulas: +L1I request rate = ICACHE_ACCESSES / INSTR_RETIRED_ANY +L1I miss rate = ICACHE_MISSES / INSTR_RETIRED_ANY +L1I miss ratio = ICACHE_MISSES / ICACHE_ACCESSES +- +This group measures some L1 instruction cache metrics. diff --git a/collectors/likwid/groups/goldmont/L2CACHE.txt b/collectors/likwid/groups/goldmont/L2CACHE.txt new file mode 100644 index 0000000..32a1545 --- /dev/null +++ b/collectors/likwid/groups/goldmont/L2CACHE.txt @@ -0,0 +1,34 @@ +SHORT L2 cache miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 LONGEST_LAT_CACHE_REFERENCE +PMC1 LONGEST_LAT_CACHE_MISS + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L2 request rate PMC0/FIXC0 +L2 miss rate PMC1/FIXC0 +L2 miss ratio PMC1/PMC0 + +LONG +Formulas: +L2 request rate = LONGEST_LAT_CACHE_REFERENCE/INSTR_RETIRED_ANY +L2 miss rate = LONGEST_LAT_CACHE_MISS/INSTR_RETIRED_ANY +L2 miss ratio = LONGEST_LAT_CACHE_MISS/LONGEST_LAT_CACHE_REFERENCE +- +This group measures the locality of your data accesses with regard to the +L2 cache. L2 request rate tells you how data intensive your code is +or how many data accesses you have on average per instruction. +The L2 miss rate gives a measure how often it was necessary to get +cache lines from memory. And finally L2 miss ratio tells you how many of your +memory references required a cache line to be loaded from a higher level. +While the data cache miss rate might be given by your algorithm you should +try to get data cache miss ratio as low as possible by increasing your cache +reuse. + diff --git a/collectors/likwid/groups/goldmont/TLB_DATA.txt b/collectors/likwid/groups/goldmont/TLB_DATA.txt new file mode 100644 index 0000000..b4679e5 --- /dev/null +++ b/collectors/likwid/groups/goldmont/TLB_DATA.txt @@ -0,0 +1,27 @@ +SHORT L2 data TLB miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 PAGE_WALKS_D_SIDE_COUNT +PMC1 PAGE_WALKS_D_SIDE_CYCLES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L1 DTLB misses PMC0 +L1 DTLB miss rate PMC0/FIXC0 +L1 DTLB miss duration [Cyc] PMC1/PMC0 + +LONG +Formulas: +L1 DTLB misses = PAGE_WALKS_D_SIDE_COUNT +L1 DTLB miss rate = PAGE_WALKS_D_SIDE_COUNT / INSTR_RETIRED_ANY +L1 DTLB miss duration [Cyc] = PAGE_WALKS_D_SIDE_CYCLES / PAGE_WALKS_D_SIDE_COUNT +- +The DTLB load and store miss rates gives a measure how often a TLB miss occurred +per instruction. The duration measures the time in cycles how long a walk did take. + diff --git a/collectors/likwid/groups/goldmont/TLB_INSTR.txt b/collectors/likwid/groups/goldmont/TLB_INSTR.txt new file mode 100644 index 0000000..30dce1e --- /dev/null +++ b/collectors/likwid/groups/goldmont/TLB_INSTR.txt @@ -0,0 +1,27 @@ +SHORT L1 Instruction TLB miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 PAGE_WALKS_I_SIDE_COUNT +PMC1 PAGE_WALKS_I_SIDE_CYCLES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L1 ITLB misses PMC0 +L1 ITLB miss rate PMC0/FIXC0 +L1 ITLB miss duration [Cyc] PMC1/PMC0 + + +LONG +Formulas: +L1 ITLB misses = PAGE_WALKS_I_SIDE_COUNT +L1 ITLB miss rate = PAGE_WALKS_I_SIDE_COUNT / INSTR_RETIRED_ANY +L1 ITLB miss duration [Cyc] = PAGE_WALKS_I_SIDE_CYCLES / PAGE_WALKS_I_SIDE_COUNT +- +The ITLB miss rates gives a measure how often a TLB miss occurred +per instruction. The duration measures the time in cycles how long a walk did take. diff --git a/collectors/likwid/groups/haswell/BRANCH.txt b/collectors/likwid/groups/haswell/BRANCH.txt new file mode 100644 index 0000000..b8d41b2 --- /dev/null +++ b/collectors/likwid/groups/haswell/BRANCH.txt @@ -0,0 +1,31 @@ +SHORT Branch prediction miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 BR_INST_RETIRED_ALL_BRANCHES +PMC1 BR_MISP_RETIRED_ALL_BRANCHES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Branch rate PMC0/FIXC0 +Branch misprediction rate PMC1/FIXC0 +Branch misprediction ratio PMC1/PMC0 +Instructions per branch FIXC0/PMC0 + +LONG +Formulas: +Branch rate = BR_INST_RETIRED_ALL_BRANCHES/INSTR_RETIRED_ANY +Branch misprediction rate = BR_MISP_RETIRED_ALL_BRANCHES/INSTR_RETIRED_ANY +Branch misprediction ratio = BR_MISP_RETIRED_ALL_BRANCHES/BR_INST_RETIRED_ALL_BRANCHES +Instructions per branch = INSTR_RETIRED_ANY/BR_INST_RETIRED_ALL_BRANCHES +- +The rates state how often on average a branch or a mispredicted branch occurred +per instruction retired in total. The branch misprediction ratio sets directly +into relation what ratio of all branch instruction where mispredicted. +Instructions per branch is 1/branch rate. + diff --git a/collectors/likwid/groups/haswell/CACHES.txt b/collectors/likwid/groups/haswell/CACHES.txt new file mode 100644 index 0000000..e39e861 --- /dev/null +++ b/collectors/likwid/groups/haswell/CACHES.txt @@ -0,0 +1,71 @@ +SHORT Cache bandwidth in MBytes/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 L1D_REPLACEMENT +PMC1 L1D_M_EVICT +PMC2 L2_LINES_IN_ALL +PMC3 L2_TRANS_L2_WB +CBOX0C0 CACHE_LOOKUP_READ_MESI +CBOX1C0 CACHE_LOOKUP_READ_MESI +CBOX2C0 CACHE_LOOKUP_READ_MESI +CBOX3C0 CACHE_LOOKUP_READ_MESI +CBOX0C1 CACHE_LOOKUP_WRITE_MESI +CBOX1C1 CACHE_LOOKUP_WRITE_MESI +CBOX2C1 CACHE_LOOKUP_WRITE_MESI +CBOX3C1 CACHE_LOOKUP_WRITE_MESI + + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L2 to L1 load bandwidth [MBytes/s] 1.0E-06*PMC0*64.0/time +L2 to L1 load data volume [GBytes] 1.0E-09*PMC0*64.0 +L1 to L2 evict bandwidth [MBytes/s] 1.0E-06*PMC1*64.0/time +L1 to L2 evict data volume [GBytes] 1.0E-09*PMC1*64.0 +L1 to/from L2 bandwidth [MBytes/s] 1.0E-06*(PMC0+PMC1)*64.0/time +L1 to/from L2 data volume [GBytes] 1.0E-09*(PMC0+PMC1)*64.0 +L3 to L2 load bandwidth [MBytes/s] 1.0E-06*PMC2*64.0/time +L3 to L2 load data volume [GBytes] 1.0E-09*PMC2*64.0 +L2 to L3 evict bandwidth [MBytes/s] 1.0E-06*PMC3*64.0/time +L2 to L3 evict data volume [GBytes] 1.0E-09*PMC3*64.0 +L2 to/from L3 bandwidth [MBytes/s] 1.0E-06*(PMC2+PMC3)*64.0/time +L2 to/from L3 data volume [GBytes] 1.0E-09*(PMC2+PMC3)*64.0 +System to L3 bandwidth [MBytes/s] 1.0E-06*(CBOX0C0+CBOX1C0+CBOX2C0+CBOX3C0)*64.0/time +System to L3 data volume [GBytes] 1.0E-09*(CBOX0C0+CBOX1C0+CBOX2C0+CBOX3C0)*64.0 +L3 to system bandwidth [MBytes/s] 1.0E-06*(CBOX0C1+CBOX1C1+CBOX2C1+CBOX3C1)*64/time +L3 to system data volume [GBytes] 1.0E-09*(CBOX0C1+CBOX1C1+CBOX2C1+CBOX3C1)*64 +L3 to/from system bandwidth [MBytes/s] 1.0E-06*(CBOX0C0+CBOX1C0+CBOX2C0+CBOX3C0+CBOX0C1+CBOX1C1+CBOX2C1+CBOX3C1)*64.0/time +L3 to/from system data volume [GBytes] 1.0E-09*(CBOX0C0+CBOX1C0+CBOX2C0+CBOX3C0+CBOX0C1+CBOX1C1+CBOX2C1+CBOX3C1)*64.0 + +LONG +Formulas: +L2 to L1 load bandwidth [MBytes/s] = 1.0E-06*L1D_REPLACEMENT*64/time +L2 to L1 load data volume [GBytes] = 1.0E-09*L1D_REPLACEMENT*64 +L1 to L2 evict bandwidth [MBytes/s] = 1.0E-06*L1D_M_EVICT*64/time +L1 to L2 evict data volume [GBytes] = 1.0E-09*L1D_M_EVICT*64 +L1 to/from L2 bandwidth [MBytes/s] = 1.0E-06*(L1D_REPLACEMENT+L1D_M_EVICT)*64/time +L1 to/from L2 data volume [GBytes] = 1.0E-09*(L1D_REPLACEMENT+L1D_M_EVICT)*64 +L3 to L2 load bandwidth [MBytes/s] = 1.0E-06*L2_LINES_IN_ALL*64/time +L3 to L2 load data volume [GBytes] = 1.0E-09*L2_LINES_IN_ALL*64 +L2 to L3 evict bandwidth [MBytes/s] = 1.0E-06*L2_TRANS_L2_WB*64/time +L2 to L3 evict data volume [GBytes] = 1.0E-09*L2_TRANS_L2_WB*64 +L2 to/from L3 bandwidth [MBytes/s] = 1.0E-06*(L2_LINES_IN_ALL+L2_TRANS_L2_WB)*64/time +L2 to/from L3 data volume [GBytes] = 1.0E-09*(L2_LINES_IN_ALL+L2_TRANS_L2_WB)*64 +System to L3 bandwidth [MBytes/s] = 1.0E-06*(SUM(CACHE_LOOKUP_READ_MESI))*64/time +System to L3 data volume [GBytes] = 1.0E-09*(SUM(CACHE_LOOKUP_READ_MESI))*64 +L3 to system bandwidth [MBytes/s] = 1.0E-06*(SUM(CACHE_LOOKUP_WRITE_MESI))*64/time +L3 to system data volume [GBytes] = 1.0E-09*(SUM(CACHE_LOOKUP_WRITE_MESI))*64 +L3 to/from system bandwidth [MBytes/s] = 1.0E-06*(SUM(CACHE_LOOKUP_READ_MESI)+SUM(CACHE_LOOKUP_WRITE_MESI))*64/time +L3 to/from system data volume [GBytes] = 1.0E-09*(SUM(CACHE_LOOKUP_READ_MESI)+SUM(CACHE_LOOKUP_WRITE_MESI))*64 +- +Group to measure cache transfers between L1 and Memory. Please notice that the +L3 to/from system metrics contain any traffic to the system (memory, +Intel QPI, etc.) but don't seem to handle anything because commonly memory read +bandwidth and L3 to L2 bandwidth is higher as the memory to L3 bandwidth. + diff --git a/collectors/likwid/groups/haswell/CLOCK.txt b/collectors/likwid/groups/haswell/CLOCK.txt new file mode 100644 index 0000000..8055d5b --- /dev/null +++ b/collectors/likwid/groups/haswell/CLOCK.txt @@ -0,0 +1,26 @@ +SHORT Power and Energy consumption + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PWR0 PWR_PKG_ENERGY +UBOXFIX UNCORE_CLOCK + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +Uncore Clock [MHz] 1.E-06*UBOXFIX/time +CPI FIXC1/FIXC0 +Energy [J] PWR0 +Power [W] PWR0/time + +LONG +Formulas: +Power = PWR_PKG_ENERGY / time +Uncore Clock [MHz] = 1.E-06 * UNCORE_CLOCK / time +- +Haswell implements the new RAPL interface. This interface enables to +monitor the consumed energy on the package (socket) level. + diff --git a/collectors/likwid/groups/haswell/CYCLE_ACTIVITY.txt b/collectors/likwid/groups/haswell/CYCLE_ACTIVITY.txt new file mode 100644 index 0000000..c432a44 --- /dev/null +++ b/collectors/likwid/groups/haswell/CYCLE_ACTIVITY.txt @@ -0,0 +1,38 @@ +SHORT Cycle Activities + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 CYCLE_ACTIVITY_CYCLES_L2_PENDING +PMC1 CYCLE_ACTIVITY_CYCLES_LDM_PENDING +PMC2 CYCLE_ACTIVITY_CYCLES_L1D_PENDING +PMC3 CYCLE_ACTIVITY_CYCLES_NO_EXECUTE + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Cycles without execution [%] (PMC3/FIXC1)*100 +Cycles without execution due to L1D [%] (PMC2/FIXC1)*100 +Cycles without execution due to L2 [%] (PMC0/FIXC1)*100 +Cycles without execution due to memory loads [%] (PMC1/FIXC1)*100 + +LONG +Formulas: +Cycles without execution [%] = CYCLE_ACTIVITY_CYCLES_NO_EXECUTE/CPU_CLK_UNHALTED_CORE*100 +Cycles with stalls due to L1D [%] = CYCLE_ACTIVITY_CYCLES_L1D_PENDING/CPU_CLK_UNHALTED_CORE*100 +Cycles with stalls due to L2 [%] = CYCLE_ACTIVITY_CYCLES_L2_PENDING/CPU_CLK_UNHALTED_CORE*100 +Cycles without execution due to memory loads [%] = CYCLE_ACTIVITY_CYCLES_LDM_PENDING/CPU_CLK_UNHALTED_CORE*100 +-- +This performance group measures the cycles while waiting for data from the cache +and memory hierarchy. +CYCLE_ACTIVITY_CYCLES_NO_EXECUTE: Counts number of cycles nothing is executed on +any execution port. +CYCLE_ACTIVITY_CYCLES_L1D_PENDING: Cycles while L1 cache miss demand load is +outstanding. +CYCLE_ACTIVITY_CYCLES_L2_PENDING: Cycles while L2 cache miss demand load is +outstanding. +CYCLE_ACTIVITY_CYCLES_LDM_PENDING: Cycles while memory subsystem has an +outstanding load. diff --git a/collectors/likwid/groups/haswell/CYCLE_STALLS.txt b/collectors/likwid/groups/haswell/CYCLE_STALLS.txt new file mode 100644 index 0000000..795aeb9 --- /dev/null +++ b/collectors/likwid/groups/haswell/CYCLE_STALLS.txt @@ -0,0 +1,45 @@ +SHORT Cycle Activities (Stalls) + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 CYCLE_ACTIVITY_STALLS_L2_PENDING +PMC1 CYCLE_ACTIVITY_STALLS_LDM_PENDING +PMC2 CYCLE_ACTIVITY_STALLS_L1D_PENDING +PMC3 CYCLE_ACTIVITY_STALLS_TOTAL + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Total execution stalls PMC3 +Stalls caused by L1D misses [%] (PMC2/PMC3)*100 +Stalls caused by L2 misses [%] (PMC0/PMC3)*100 +Stalls caused by memory loads [%] (PMC1/PMC3)*100 +Execution stall rate [%] (PMC3/FIXC1)*100 +Stalls caused by L1D misses rate [%] (PMC2/FIXC1)*100 +Stalls caused by L2 misses rate [%] (PMC0/FIXC1)*100 +Stalls caused by memory loads rate [%] (PMC1/FIXC1)*100 + +LONG +Formulas: +Total execution stalls = CYCLE_ACTIVITY_STALLS_TOTAL +Stalls caused by L1D misses [%] = (CYCLE_ACTIVITY_STALLS_L1D_PENDING/CYCLE_ACTIVITY_STALLS_TOTAL)*100 +Stalls caused by L2 misses [%] = (CYCLE_ACTIVITY_STALLS_L2_PENDING/CYCLE_ACTIVITY_STALLS_TOTAL)*100 +Stalls caused by memory loads [%] = (CYCLE_ACTIVITY_STALLS_LDM_PENDING/CYCLE_ACTIVITY_STALLS_TOTAL)*100 +Execution stall rate [%] = (CYCLE_ACTIVITY_STALLS_TOTAL/CPU_CLK_UNHALTED_CORE)*100 +Stalls caused by L1D misses rate [%] = (CYCLE_ACTIVITY_STALLS_L1D_PENDING/CPU_CLK_UNHALTED_CORE)*100 +Stalls caused by L2 misses rate [%] = (CYCLE_ACTIVITY_STALLS_L2_PENDING/CPU_CLK_UNHALTED_CORE)*100 +Stalls caused by memory loads rate [%] = (CYCLE_ACTIVITY_STALLS_LDM_PENDING/CPU_CLK_UNHALTED_CORE)*100 +-- +This performance group measures the stalls caused by data traffic in the cache +hierarchy. +CYCLE_ACTIVITY_STALLS_TOTAL: Total execution stalls. +CYCLE_ACTIVITY_STALLS_L1D_PENDING: Execution stalls while L1 cache miss demand +load is outstanding. +CYCLE_ACTIVITY_STALLS_L2_PENDING: Execution stalls while L2 cache miss demand +load is outstanding. +CYCLE_ACTIVITY_STALLS_LDM_PENDING: Execution stalls while memory subsystem has +an outstanding load. diff --git a/collectors/likwid/groups/haswell/DATA.txt b/collectors/likwid/groups/haswell/DATA.txt new file mode 100644 index 0000000..17948d4 --- /dev/null +++ b/collectors/likwid/groups/haswell/DATA.txt @@ -0,0 +1,27 @@ +SHORT Load to store ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 MEM_UOPS_RETIRED_LOADS +PMC1 MEM_UOPS_RETIRED_STORES +PMC2 UOPS_RETIRED_ALL + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Load to store ratio PMC0/PMC1 +Load ratio PMC0/PMC2 +Store ratio PMC1/PMC2 + +LONG +Formulas: +Load to store ratio = MEM_UOPS_RETIRED_LOADS/MEM_UOPS_RETIRED_STORES +Load ratio = MEM_UOPS_RETIRED_LOADS/UOPS_RETIRED_ALL +Store ratio = MEM_UOPS_RETIRED_STORES/UOPS_RETIRED_ALL +- +This is a metric to determine your load to store ratio. + diff --git a/collectors/likwid/groups/haswell/DIVIDE.txt b/collectors/likwid/groups/haswell/DIVIDE.txt new file mode 100644 index 0000000..c9690cf --- /dev/null +++ b/collectors/likwid/groups/haswell/DIVIDE.txt @@ -0,0 +1,24 @@ +SHORT Divide unit information + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 ARITH_DIVIDER_UOPS +PMC1 ARITH_DIVIDER_CYCLES + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Number of divide ops PMC0 +Avg. divide unit usage duration PMC1/PMC0 + +LONG +Formulas: +Number of divide ops = ARITH_DIVIDER_UOPS +Avg. divide unit usage duration = ARITH_DIVIDER_CYCLES/ARITH_DIVIDER_UOPS +- +This performance group measures the average latency of divide operations diff --git a/collectors/likwid/groups/haswell/ENERGY.txt b/collectors/likwid/groups/haswell/ENERGY.txt new file mode 100644 index 0000000..59242db --- /dev/null +++ b/collectors/likwid/groups/haswell/ENERGY.txt @@ -0,0 +1,39 @@ +SHORT Power and Energy consumption + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +TMP0 TEMP_CORE +PWR0 PWR_PKG_ENERGY +PWR1 PWR_PP0_ENERGY +PWR2 PWR_PP1_ENERGY +PWR3 PWR_DRAM_ENERGY + + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Temperature [C] TMP0 +Energy [J] PWR0 +Power [W] PWR0/time +Energy PP0 [J] PWR1 +Power PP0 [W] PWR1/time +Energy PP1 [J] PWR2 +Power PP1 [W] PWR2/time +Energy DRAM [J] PWR3 +Power DRAM [W] PWR3/time + +LONG +Formulas: +Power = PWR_PKG_ENERGY / time +Power PP0 = PWR_PP0_ENERGY / time +Power PP1 = PWR_PP1_ENERGY / time +Power DRAM = PWR_DRAM_ENERGY / time +- +Haswell implements the new RAPL interface. This interface enables to +monitor the consumed energy on the package (socket) and DRAM level. + diff --git a/collectors/likwid/groups/haswell/FALSE_SHARE.txt b/collectors/likwid/groups/haswell/FALSE_SHARE.txt new file mode 100644 index 0000000..db438a3 --- /dev/null +++ b/collectors/likwid/groups/haswell/FALSE_SHARE.txt @@ -0,0 +1,27 @@ +SHORT False sharing + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 MEM_LOAD_UOPS_L3_HIT_RETIRED_XSNP_HITM +PMC2 MEM_LOAD_UOPS_RETIRED_ALL_ALL + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Local LLC hit with false sharing [MByte] 1.E-06*PMC0*64 +Local LLC hit with false sharing rate PMC0/PMC2 + +LONG +Formulas: +Local LLC false sharing [MByte] = 1.E-06*MEM_LOAD_UOPS_L3_HIT_RETIRED_XSNP_HITM*64 +Local LLC false sharing rate = MEM_LOAD_UOPS_L3_HIT_RETIRED_XSNP_HITM/MEM_LOAD_UOPS_RETIRED_ALL +- +False-sharing of cache lines can dramatically reduce the performance of an +application. This performance group measures the L3 traffic induced by false-sharing. +The false-sharing rate uses all memory loads as reference. +Please keep in mind that the MEM_LOAD_UOPS_L3_HIT_RETIRED_XSNP_HITM event may +undercount by as much as 40% (Errata HSD25). diff --git a/collectors/likwid/groups/haswell/FLOPS_AVX.txt b/collectors/likwid/groups/haswell/FLOPS_AVX.txt new file mode 100644 index 0000000..15aacb8 --- /dev/null +++ b/collectors/likwid/groups/haswell/FLOPS_AVX.txt @@ -0,0 +1,28 @@ +SHORT Packed AVX MFLOP/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 AVX_INSTS_CALC + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Packed SP [MFLOP/s] 1.0E-06*(PMC0*8.0)/time +Packed DP [MFLOP/s] 1.0E-06*(PMC0*4.0)/time + +LONG +Formulas: +Packed SP [MFLOP/s] = 1.0E-06*(AVX_INSTS_CALC*8)/runtime +Packed DP [MFLOP/s] = 1.0E-06*(AVX_INSTS_CALC*4)/runtime +- +Packed 32b AVX FLOP/s rates. Approximate counts of AVX & AVX2 256-bit instructions. +May count non-AVX instructions that employ 256-bit operations, including (but +not necessarily limited to) rep string instructions that use 256-bit loads and +stores for optimized performance, XSAVE* and XRSTOR*, and operations that +transition the x87 FPU data registers between x87 and MMX. +Caution: The event AVX_INSTS_CALC counts the insertf128 instruction often used +by the Intel C compilers for (unaligned) vector loads. diff --git a/collectors/likwid/groups/haswell/ICACHE.txt b/collectors/likwid/groups/haswell/ICACHE.txt new file mode 100644 index 0000000..f1e2335 --- /dev/null +++ b/collectors/likwid/groups/haswell/ICACHE.txt @@ -0,0 +1,33 @@ +SHORT Instruction cache miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 ICACHE_ACCESSES +PMC1 ICACHE_MISSES +PMC2 ICACHE_IFETCH_STALL +PMC3 ILD_STALL_IQ_FULL + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L1I request rate PMC0/FIXC0 +L1I miss rate PMC1/FIXC0 +L1I miss ratio PMC1/PMC0 +L1I stalls PMC2 +L1I stall rate PMC2/FIXC0 +L1I queue full stalls PMC3 +L1I queue full stall rate PMC3/FIXC0 + +LONG +Formulas: +L1I request rate = ICACHE_ACCESSES / INSTR_RETIRED_ANY +L1I miss rate = ICACHE_MISSES / INSTR_RETIRED_ANY +L1I miss ratio = ICACHE_MISSES / ICACHE_ACCESSES +L1I stalls = ICACHE_IFETCH_STALL +L1I stall rate = ICACHE_IFETCH_STALL / INSTR_RETIRED_ANY +- +This group measures some L1 instruction cache metrics. diff --git a/collectors/likwid/groups/haswell/L2.txt b/collectors/likwid/groups/haswell/L2.txt new file mode 100644 index 0000000..60c7f79 --- /dev/null +++ b/collectors/likwid/groups/haswell/L2.txt @@ -0,0 +1,37 @@ +SHORT L2 cache bandwidth in MBytes/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 L1D_REPLACEMENT +PMC1 L2_TRANS_L1D_WB +PMC2 ICACHE_MISSES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L2D load bandwidth [MBytes/s] 1.0E-06*PMC0*64.0/time +L2D load data volume [GBytes] 1.0E-09*PMC0*64.0 +L2D evict bandwidth [MBytes/s] 1.0E-06*PMC1*64.0/time +L2D evict data volume [GBytes] 1.0E-09*PMC1*64.0 +L2 bandwidth [MBytes/s] 1.0E-06*(PMC0+PMC1+PMC2)*64.0/time +L2 data volume [GBytes] 1.0E-09*(PMC0+PMC1+PMC2)*64.0 + +LONG +Formulas: +L2D load bandwidth [MBytes/s] = 1.0E-06*L1D_REPLACEMENT*64.0/time +L2D load data volume [GBytes] = 1.0E-09*L1D_REPLACEMENT*64.0 +L2D evict bandwidth [MBytes/s] = 1.0E-06*L2_TRANS_L1D_WB*64.0/time +L2D evict data volume [GBytes] = 1.0E-09*L2_TRANS_L1D_WB*64.0 +L2 bandwidth [MBytes/s] = 1.0E-06*(L1D_REPLACEMENT+L2_TRANS_L1D_WB+ICACHE_MISSES)*64.0/time +L2 data volume [GBytes] = 1.0E-09*(L1D_REPLACEMENT+L2_TRANS_L1D_WB+ICACHE_MISSES)*64.0 +- +Profiling group to measure L2 cache bandwidth. The bandwidth is computed by the +number of cache line loaded from the L2 to the L2 data cache and the writebacks from +the L2 data cache to the L2 cache. The group also outputs total data volume transferred between +L2 and L1. Note that this bandwidth also includes data transfers due to a write +allocate load on a store miss in L1 and cache lines transferred it the instruction +cache. diff --git a/collectors/likwid/groups/haswell/L2CACHE.txt b/collectors/likwid/groups/haswell/L2CACHE.txt new file mode 100644 index 0000000..9b5dd4b --- /dev/null +++ b/collectors/likwid/groups/haswell/L2CACHE.txt @@ -0,0 +1,34 @@ +SHORT L2 cache miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 L2_TRANS_ALL_REQUESTS +PMC1 L2_RQSTS_MISS + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L2 request rate PMC0/FIXC0 +L2 miss rate PMC1/FIXC0 +L2 miss ratio PMC1/PMC0 + +LONG +Formulas: +L2 request rate = L2_TRANS_ALL_REQUESTS/INSTR_RETIRED_ANY +L2 miss rate = L2_RQSTS_MISS/INSTR_RETIRED_ANY +L2 miss ratio = L2_RQSTS_MISS/L2_TRANS_ALL_REQUESTS +- +This group measures the locality of your data accesses with regard to the +L2 cache. L2 request rate tells you how data intensive your code is +or how many data accesses you have on average per instruction. +The L2 miss rate gives a measure how often it was necessary to get +cache lines from memory. And finally L2 miss ratio tells you how many of your +memory references required a cache line to be loaded from a higher level. +While the# data cache miss rate might be given by your algorithm you should +try to get data cache miss ratio as low as possible by increasing your cache reuse. + + diff --git a/collectors/likwid/groups/haswell/L3.txt b/collectors/likwid/groups/haswell/L3.txt new file mode 100644 index 0000000..f63a918 --- /dev/null +++ b/collectors/likwid/groups/haswell/L3.txt @@ -0,0 +1,36 @@ +SHORT L3 cache bandwidth in MBytes/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 L2_LINES_IN_ALL +PMC1 L2_TRANS_L2_WB + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L3 load bandwidth [MBytes/s] 1.0E-06*PMC0*64.0/time +L3 load data volume [GBytes] 1.0E-09*PMC0*64.0 +L3 evict bandwidth [MBytes/s] 1.0E-06*PMC1*64.0/time +L3 evict data volume [GBytes] 1.0E-09*PMC1*64.0 +L3 bandwidth [MBytes/s] 1.0E-06*(PMC0+PMC1)*64.0/time +L3 data volume [GBytes] 1.0E-09*(PMC0+PMC1)*64.0 + +LONG +Formulas: +L3 load bandwidth [MBytes/s] = 1.0E-06*L2_LINES_IN_ALL*64.0/time +L3 load data volume [GBytes] = 1.0E-09*L2_LINES_IN_ALL*64.0 +L3 evict bandwidth [MBytes/s] = 1.0E-06*L2_TRANS_L2_WB*64.0/time +L3 evict data volume [GBytes] = 1.0E-09*L2_TRANS_L2_WB*64.0 +L3 bandwidth [MBytes/s] = 1.0E-06*(L2_LINES_IN_ALL+L2_TRANS_L2_WB)*64/time +L3 data volume [GBytes] = 1.0E-09*(L2_LINES_IN_ALL+L2_TRANS_L2_WB)*64 +- +Profiling group to measure L3 cache bandwidth. The bandwidth is computed by the +number of cache line allocated in the L2 and the number of modified cache lines +evicted from the L2. This group also output data volume transferred between the +L3 and measured cores L2 caches. Note that this bandwidth also includes data +transfers due to a write allocate load on a store miss in L2. + diff --git a/collectors/likwid/groups/haswell/L3CACHE.txt b/collectors/likwid/groups/haswell/L3CACHE.txt new file mode 100644 index 0000000..f863daa --- /dev/null +++ b/collectors/likwid/groups/haswell/L3CACHE.txt @@ -0,0 +1,35 @@ +SHORT L3 cache miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 MEM_LOAD_UOPS_RETIRED_L3_ALL +PMC1 MEM_LOAD_UOPS_RETIRED_L3_MISS +PMC2 UOPS_RETIRED_ALL + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L3 request rate PMC0/PMC2 +L3 miss rate PMC1/PMC2 +L3 miss ratio PMC1/PMC0 + +LONG +Formulas: +L3 request rate = MEM_LOAD_UOPS_RETIRED_L3_ALL/UOPS_RETIRED_ALL +L3 miss rate = MEM_LOAD_UOPS_RETIRED_L3_MISS/UOPS_RETIRED_ALL +L3 miss ratio = MEM_LOAD_UOPS_RETIRED_L3_MISS/MEM_LOAD_UOPS_RETIRED_L3_ALL +- +This group measures the locality of your data accesses with regard to the +L3 cache. L3 request rate tells you how data intensive your code is +or how many data accesses you have on average per instruction. +The L3 miss rate gives a measure how often it was necessary to get +cache lines from memory. And finally L3 miss ratio tells you how many of your +memory references required a cache line to be loaded from a higher level. +While the# data cache miss rate might be given by your algorithm you should +try to get data cache miss ratio as low as possible by increasing your cache reuse. + + diff --git a/collectors/likwid/groups/haswell/MEM.txt b/collectors/likwid/groups/haswell/MEM.txt new file mode 100644 index 0000000..3a12df7 --- /dev/null +++ b/collectors/likwid/groups/haswell/MEM.txt @@ -0,0 +1,36 @@ +SHORT L3 cache bandwidth in MBytes/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +MBOX0C1 DRAM_READS +MBOX0C2 DRAM_WRITES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Memory load bandwidth [MBytes/s] 1.0E-06*MBOX0C1*64.0/time +Memory load data volume [GBytes] 1.0E-09*MBOX0C1*64.0 +Memory evict bandwidth [MBytes/s] 1.0E-06*MBOX0C2*64.0/time +Memory evict data volume [GBytes] 1.0E-09*MBOX0C2*64.0 +Memory bandwidth [MBytes/s] 1.0E-06*(MBOX0C1+MBOX0C2)*64.0/time +Memory data volume [GBytes] 1.0E-09*(MBOX0C1+MBOX0C2)*64.0 + +LONG +Formulas: +L3 load bandwidth [MBytes/s] = 1.0E-06*L2_LINES_IN_ALL*64.0/time +L3 load data volume [GBytes] = 1.0E-09*L2_LINES_IN_ALL*64.0 +L3 evict bandwidth [MBytes/s] = 1.0E-06*L2_TRANS_L2_WB*64.0/time +L3 evict data volume [GBytes] = 1.0E-09*L2_TRANS_L2_WB*64.0 +L3 bandwidth [MBytes/s] = 1.0E-06*(L2_LINES_IN_ALL+L2_TRANS_L2_WB)*64/time +L3 data volume [GBytes] = 1.0E-09*(L2_LINES_IN_ALL+L2_TRANS_L2_WB)*64 +- +Profiling group to measure L3 cache bandwidth. The bandwidth is computed by the +number of cache line allocated in the L2 and the number of modified cache lines +evicted from the L2. This group also output data volume transferred between the +L3 and measured cores L2 caches. Note that this bandwidth also includes data +transfers due to a write allocate load on a store miss in L2. + diff --git a/collectors/likwid/groups/haswell/PORT_USAGE.txt b/collectors/likwid/groups/haswell/PORT_USAGE.txt new file mode 100644 index 0000000..eb74ffe --- /dev/null +++ b/collectors/likwid/groups/haswell/PORT_USAGE.txt @@ -0,0 +1,46 @@ +SHORT Execution port utilization + +REQUIRE_NOHT + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 UOPS_EXECUTED_PORT_PORT_0 +PMC1 UOPS_EXECUTED_PORT_PORT_1 +PMC2 UOPS_EXECUTED_PORT_PORT_2 +PMC3 UOPS_EXECUTED_PORT_PORT_3 +PMC4 UOPS_EXECUTED_PORT_PORT_4 +PMC5 UOPS_EXECUTED_PORT_PORT_5 +PMC6 UOPS_EXECUTED_PORT_PORT_6 +PMC7 UOPS_EXECUTED_PORT_PORT_7 + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Port0 usage ratio PMC0/(PMC0+PMC1+PMC2+PMC3+PMC4+PMC5+PMC6+PMC7) +Port1 usage ratio PMC1/(PMC0+PMC1+PMC2+PMC3+PMC4+PMC5+PMC6+PMC7) +Port2 usage ratio PMC2/(PMC0+PMC1+PMC2+PMC3+PMC4+PMC5+PMC6+PMC7) +Port3 usage ratio PMC3/(PMC0+PMC1+PMC2+PMC3+PMC4+PMC5+PMC6+PMC7) +Port4 usage ratio PMC4/(PMC0+PMC1+PMC2+PMC3+PMC4+PMC5+PMC6+PMC7) +Port5 usage ratio PMC5/(PMC0+PMC1+PMC2+PMC3+PMC4+PMC5+PMC6+PMC7) +Port6 usage ratio PMC6/(PMC0+PMC1+PMC2+PMC3+PMC4+PMC5+PMC6+PMC7) +Port7 usage ratio PMC7/(PMC0+PMC1+PMC2+PMC3+PMC4+PMC5+PMC6+PMC7) + +LONG +Formulas: +Port0 usage ratio = UOPS_EXECUTED_PORT_PORT_0/SUM(UOPS_EXECUTED_PORT_PORT_*) +Port1 usage ratio = UOPS_EXECUTED_PORT_PORT_1/SUM(UOPS_EXECUTED_PORT_PORT_*) +Port2 usage ratio = UOPS_EXECUTED_PORT_PORT_2/SUM(UOPS_EXECUTED_PORT_PORT_*) +Port3 usage ratio = UOPS_EXECUTED_PORT_PORT_3/SUM(UOPS_EXECUTED_PORT_PORT_*) +Port4 usage ratio = UOPS_EXECUTED_PORT_PORT_4/SUM(UOPS_EXECUTED_PORT_PORT_*) +Port5 usage ratio = UOPS_EXECUTED_PORT_PORT_5/SUM(UOPS_EXECUTED_PORT_PORT_*) +Port6 usage ratio = UOPS_EXECUTED_PORT_PORT_6/SUM(UOPS_EXECUTED_PORT_PORT_*) +Port7 usage ratio = UOPS_EXECUTED_PORT_PORT_7/SUM(UOPS_EXECUTED_PORT_PORT_*) +- +This group measures the execution port utilization in a CPU core. The group can +only be measured when HyperThreading is disabled because only then each CPU core +can program eight counters. diff --git a/collectors/likwid/groups/haswell/RECOVERY.txt b/collectors/likwid/groups/haswell/RECOVERY.txt new file mode 100644 index 0000000..7928ee4 --- /dev/null +++ b/collectors/likwid/groups/haswell/RECOVERY.txt @@ -0,0 +1,22 @@ +SHORT Recovery duration + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 INT_MISC_RECOVERY_CYCLES +PMC1 INT_MISC_RECOVERY_COUNT + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Avg. recovery duration PMC0/PMC1 + +LONG +Formulas: +Avg. recovery duration = INT_MISC_RECOVERY_CYCLES/INT_MISC_RECOVERY_COUNT +- +This group measures the duration of recoveries after SSE exception, memory +disambiguation, etc... diff --git a/collectors/likwid/groups/haswell/TLB_DATA.txt b/collectors/likwid/groups/haswell/TLB_DATA.txt new file mode 100644 index 0000000..8d94e05 --- /dev/null +++ b/collectors/likwid/groups/haswell/TLB_DATA.txt @@ -0,0 +1,35 @@ +SHORT L2 data TLB miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 DTLB_LOAD_MISSES_CAUSES_A_WALK +PMC1 DTLB_STORE_MISSES_CAUSES_A_WALK +PMC2 DTLB_LOAD_MISSES_WALK_DURATION +PMC3 DTLB_STORE_MISSES_WALK_DURATION + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L1 DTLB load misses PMC0 +L1 DTLB load miss rate PMC0/FIXC0 +L1 DTLB load miss duration [Cyc] PMC2/PMC0 +L1 DTLB store misses PMC1 +L1 DTLB store miss rate PMC1/FIXC0 +L1 DTLB store miss duration [Cyc] PMC3/PMC1 + +LONG +Formulas: +L1 DTLB load misses = DTLB_LOAD_MISSES_CAUSES_A_WALK +L1 DTLB load miss rate = DTLB_LOAD_MISSES_CAUSES_A_WALK / INSTR_RETIRED_ANY +L1 DTLB load miss duration [Cyc] = DTLB_LOAD_MISSES_WALK_DURATION / DTLB_LOAD_MISSES_CAUSES_A_WALK +L1 DTLB store misses = DTLB_STORE_MISSES_CAUSES_A_WALK +L1 DTLB store miss rate = DTLB_STORE_MISSES_CAUSES_A_WALK / INSTR_RETIRED_ANY +L1 DTLB store miss duration [Cyc] = DTLB_STORE_MISSES_WALK_DURATION / DTLB_STORE_MISSES_CAUSES_A_WALK +- +The DTLB load and store miss rates gives a measure how often a TLB miss occurred +per instruction. The duration measures the time in cycles how long a walk did take. + diff --git a/collectors/likwid/groups/haswell/TLB_INSTR.txt b/collectors/likwid/groups/haswell/TLB_INSTR.txt new file mode 100644 index 0000000..235d977 --- /dev/null +++ b/collectors/likwid/groups/haswell/TLB_INSTR.txt @@ -0,0 +1,28 @@ +SHORT L1 Instruction TLB miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 ITLB_MISSES_CAUSES_A_WALK +PMC1 ITLB_MISSES_WALK_DURATION + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L1 ITLB misses PMC0 +L1 ITLB miss rate PMC0/FIXC0 +L1 ITLB miss duration [Cyc] PMC1/PMC0 + + +LONG +Formulas: +L1 ITLB misses = ITLB_MISSES_CAUSES_A_WALK +L1 ITLB miss rate = ITLB_MISSES_CAUSES_A_WALK / INSTR_RETIRED_ANY +L1 ITLB miss duration [Cyc] = ITLB_MISSES_WALK_DURATION / ITLB_MISSES_CAUSES_A_WALK +- +The ITLB miss rates gives a measure how often a TLB miss occurred +per instruction. The duration measures the time in cycles how long a walk did take. + diff --git a/collectors/likwid/groups/haswell/TMA.txt b/collectors/likwid/groups/haswell/TMA.txt new file mode 100644 index 0000000..afb4126 --- /dev/null +++ b/collectors/likwid/groups/haswell/TMA.txt @@ -0,0 +1,48 @@ +SHORT Top down cycle allocation + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 UOPS_ISSUED_ANY +PMC1 UOPS_RETIRED_RETIRE_SLOTS +PMC2 IDQ_UOPS_NOT_DELIVERED_CORE +PMC3 INT_MISC_RECOVERY_CYCLES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +IPC FIXC0/FIXC1 +Total Slots 4*FIXC1 +Slots Retired PMC1 +Fetch Bubbles PMC2 +Recovery Bubbles 4*PMC3 +Front End [%] PMC2/(4*FIXC1)*100 +Speculation [%] (PMC0-PMC1+(4*PMC3))/(4*FIXC1)*100 +Retiring [%] PMC1/(4*FIXC1)*100 +Back End [%] (1-((PMC2+PMC0+(4*PMC3))/(4*FIXC1)))*100 + +LONG +Formulas: +Total Slots = 4*CPU_CLK_UNHALTED_CORE +Slots Retired = UOPS_RETIRED_RETIRE_SLOTS +Fetch Bubbles = IDQ_UOPS_NOT_DELIVERED_CORE +Recovery Bubbles = 4*INT_MISC_RECOVERY_CYCLES +Front End [%] = IDQ_UOPS_NOT_DELIVERED_CORE/(4*CPU_CLK_UNHALTED_CORE)*100 +Speculation [%] = (UOPS_ISSUED_ANY-UOPS_RETIRED_RETIRE_SLOTS+(4*INT_MISC_RECOVERY_CYCLES))/(4*CPU_CLK_UNHALTED_CORE)*100 +Retiring [%] = UOPS_RETIRED_RETIRE_SLOTS/(4*CPU_CLK_UNHALTED_CORE)*100 +Back End [%] = (1-((IDQ_UOPS_NOT_DELIVERED_CORE+UOPS_ISSUED_ANY+(4*INT_MISC_RECOVERY_CYCLES))/(4*CPU_CLK_UNHALTED_CORE)))*100 +-- +This performance group measures cycles to determine percentage of time spent in +front end, back end, retiring and speculation. These metrics are published and +verified by Intel. Further information: +Webpage describing Top-Down Method and its usage in Intel vTune: +https://software.intel.com/en-us/vtune-amplifier-help-tuning-applications-using-a-top-down-microarchitecture-analysis-method +Paper by Yasin Ahmad: +https://sites.google.com/site/analysismethods/yasin-pubs/TopDown-Yasin-ISPASS14.pdf?attredirects=0 +Slides by Yasin Ahmad: +http://www.cs.technion.ac.il/~erangi/TMA_using_Linux_perf__Ahmad_Yasin.pdf +The performance group was originally published here: +http://perf.mvermeulen.com/2018/04/14/top-down-performance-counter-analysis-part-1-likwid/ diff --git a/collectors/likwid/groups/haswell/UOPS.txt b/collectors/likwid/groups/haswell/UOPS.txt new file mode 100644 index 0000000..e6cc208 --- /dev/null +++ b/collectors/likwid/groups/haswell/UOPS.txt @@ -0,0 +1,35 @@ +SHORT UOPs execution info + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 UOPS_ISSUED_ANY +PMC1 UOPS_EXECUTED_THREAD +PMC2 UOPS_RETIRED_ALL +PMC3 UOPS_ISSUED_FLAGS_MERGE + + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Issued UOPs PMC0 +Merged UOPs PMC3 +Executed UOPs PMC1 +Retired UOPs PMC2 + +LONG +Formulas: +Issued UOPs = UOPS_ISSUED_ANY +Merged UOPs = UOPS_ISSUED_FLAGS_MERGE +Executed UOPs = UOPS_EXECUTED_THREAD +Retired UOPs = UOPS_RETIRED_ALL +- +This group returns information about the instruction pipeline. It measures the +issued, executed and retired uOPs and returns the number of uOPs which were issued +but not executed as well as the number of uOPs which were executed but never retired. +The executed but not retired uOPs commonly come from speculatively executed branches. + diff --git a/collectors/likwid/groups/haswell/UOPS_EXEC.txt b/collectors/likwid/groups/haswell/UOPS_EXEC.txt new file mode 100644 index 0000000..7042df7 --- /dev/null +++ b/collectors/likwid/groups/haswell/UOPS_EXEC.txt @@ -0,0 +1,31 @@ +SHORT UOPs execution + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 UOPS_EXECUTED_USED_CYCLES +PMC1 UOPS_EXECUTED_STALL_CYCLES +PMC2 CPU_CLOCK_UNHALTED_TOTAL_CYCLES +PMC3:EDGEDETECT UOPS_EXECUTED_STALL_CYCLES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Used cycles ratio [%] 100*PMC0/PMC2 +Unused cycles ratio [%] 100*PMC1/PMC2 +Avg stall duration [cycles] PMC1/PMC3:EDGEDETECT + + +LONG +Formulas: +Used cycles ratio [%] = 100*UOPS_EXECUTED_USED_CYCLES/CPU_CLK_UNHALTED_CORE +Unused cycles ratio [%] = 100*UOPS_EXECUTED_STALL_CYCLES/CPU_CLK_UNHALTED_CORE +Avg stall duration [cycles] = UOPS_EXECUTED_STALL_CYCLES/UOPS_EXECUTED_STALL_CYCLES:EDGEDETECT +- +This performance group returns the ratios of used and unused cycles regarding +the execution stage in the pipeline. Used cycles are all cycles where uOPs are +executed while unused cycles refer to pipeline stalls. Moreover, the group +calculates the average stall duration in cycles. diff --git a/collectors/likwid/groups/haswell/UOPS_ISSUE.txt b/collectors/likwid/groups/haswell/UOPS_ISSUE.txt new file mode 100644 index 0000000..9aac923 --- /dev/null +++ b/collectors/likwid/groups/haswell/UOPS_ISSUE.txt @@ -0,0 +1,31 @@ +SHORT UOPs issueing + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 UOPS_ISSUED_USED_CYCLES +PMC1 UOPS_ISSUED_STALL_CYCLES +PMC2 CPU_CLOCK_UNHALTED_TOTAL_CYCLES +PMC3:EDGEDETECT UOPS_ISSUED_STALL_CYCLES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Used cycles ratio [%] 100*PMC0/PMC2 +Unused cycles ratio [%] 100*PMC1/PMC2 +Avg stall duration [cycles] PMC1/PMC3:EDGEDETECT + + +LONG +Formulas: +Used cycles ratio [%] = 100*UOPS_ISSUED_USED_CYCLES/CPU_CLK_UNHALTED_CORE +Unused cycles ratio [%] = 100*UOPS_ISSUED_STALL_CYCLES/CPU_CLK_UNHALTED_CORE +Avg stall duration [cycles] = UOPS_ISSUED_STALL_CYCLES/UOPS_ISSUED_STALL_CYCLES:EDGEDETECT +- +This performance group returns the ratios of used and unused cycles regarding +the issue stage in the pipeline. Used cycles are all cycles where uOPs are +issued while unused cycles refer to pipeline stalls. Moreover, the group +calculates the average stall duration in cycles. diff --git a/collectors/likwid/groups/haswell/UOPS_RETIRE.txt b/collectors/likwid/groups/haswell/UOPS_RETIRE.txt new file mode 100644 index 0000000..0f37585 --- /dev/null +++ b/collectors/likwid/groups/haswell/UOPS_RETIRE.txt @@ -0,0 +1,31 @@ +SHORT UOPs retirement + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 UOPS_RETIRED_USED_CYCLES +PMC1 UOPS_RETIRED_STALL_CYCLES +PMC2 CPU_CLOCK_UNHALTED_TOTAL_CYCLES +PMC3:EDGEDETECT UOPS_RETIRED_STALL_CYCLES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Used cycles ratio [%] 100*PMC0/PMC2 +Unused cycles ratio [%] 100*PMC1/PMC2 +Avg stall duration [cycles] PMC1/PMC3:EDGEDETECT + + +LONG +Formulas: +Used cycles ratio [%] = 100*UOPS_RETIRED_USED_CYCLES/CPU_CLK_UNHALTED_CORE +Unused cycles ratio [%] = 100*UOPS_RETIRED_STALL_CYCLES/CPU_CLK_UNHALTED_CORE +Avg stall duration [cycles] = UOPS_RETIRED_STALL_CYCLES/UOPS_RETIRED_STALL_CYCLES:EDGEDETECT +- +This performance group returns the ratios of used and unused cycles regarding +the retirement stage in the pipeline (re-order buffer). Used cycles are all +cycles where uOPs are retired while unused cycles refer to pipeline stalls. +Moreover, the group calculates the average stall duration in cycles. diff --git a/collectors/likwid/groups/haswellEP/BRANCH.txt b/collectors/likwid/groups/haswellEP/BRANCH.txt new file mode 100644 index 0000000..b8d41b2 --- /dev/null +++ b/collectors/likwid/groups/haswellEP/BRANCH.txt @@ -0,0 +1,31 @@ +SHORT Branch prediction miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 BR_INST_RETIRED_ALL_BRANCHES +PMC1 BR_MISP_RETIRED_ALL_BRANCHES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Branch rate PMC0/FIXC0 +Branch misprediction rate PMC1/FIXC0 +Branch misprediction ratio PMC1/PMC0 +Instructions per branch FIXC0/PMC0 + +LONG +Formulas: +Branch rate = BR_INST_RETIRED_ALL_BRANCHES/INSTR_RETIRED_ANY +Branch misprediction rate = BR_MISP_RETIRED_ALL_BRANCHES/INSTR_RETIRED_ANY +Branch misprediction ratio = BR_MISP_RETIRED_ALL_BRANCHES/BR_INST_RETIRED_ALL_BRANCHES +Instructions per branch = INSTR_RETIRED_ANY/BR_INST_RETIRED_ALL_BRANCHES +- +The rates state how often on average a branch or a mispredicted branch occurred +per instruction retired in total. The branch misprediction ratio sets directly +into relation what ratio of all branch instruction where mispredicted. +Instructions per branch is 1/branch rate. + diff --git a/collectors/likwid/groups/haswellEP/CACHES.txt b/collectors/likwid/groups/haswellEP/CACHES.txt new file mode 100644 index 0000000..295a139 --- /dev/null +++ b/collectors/likwid/groups/haswellEP/CACHES.txt @@ -0,0 +1,123 @@ +SHORT Cache bandwidth in MBytes/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 L1D_REPLACEMENT +PMC1 L1D_M_EVICT +PMC2 L2_LINES_IN_ALL +PMC3 L2_TRANS_L2_WB +CBOX0C0 LLC_LOOKUP_DATA_READ +CBOX1C0 LLC_LOOKUP_DATA_READ +CBOX2C0 LLC_LOOKUP_DATA_READ +CBOX3C0 LLC_LOOKUP_DATA_READ +CBOX4C0 LLC_LOOKUP_DATA_READ +CBOX5C0 LLC_LOOKUP_DATA_READ +CBOX6C0 LLC_LOOKUP_DATA_READ +CBOX7C0 LLC_LOOKUP_DATA_READ +CBOX8C0 LLC_LOOKUP_DATA_READ +CBOX9C0 LLC_LOOKUP_DATA_READ +CBOX10C0 LLC_LOOKUP_DATA_READ +CBOX11C0 LLC_LOOKUP_DATA_READ +CBOX12C0 LLC_LOOKUP_DATA_READ +CBOX13C0 LLC_LOOKUP_DATA_READ +CBOX14C0 LLC_LOOKUP_DATA_READ +CBOX15C0 LLC_LOOKUP_DATA_READ +CBOX16C0 LLC_LOOKUP_DATA_READ +CBOX17C0 LLC_LOOKUP_DATA_READ +CBOX0C1 LLC_VICTIMS_M +CBOX1C1 LLC_VICTIMS_M +CBOX2C1 LLC_VICTIMS_M +CBOX3C1 LLC_VICTIMS_M +CBOX4C1 LLC_VICTIMS_M +CBOX5C1 LLC_VICTIMS_M +CBOX6C1 LLC_VICTIMS_M +CBOX7C1 LLC_VICTIMS_M +CBOX8C1 LLC_VICTIMS_M +CBOX9C1 LLC_VICTIMS_M +CBOX10C1 LLC_VICTIMS_M +CBOX11C1 LLC_VICTIMS_M +CBOX12C1 LLC_VICTIMS_M +CBOX13C1 LLC_VICTIMS_M +MBOX0C0 CAS_COUNT_RD +MBOX0C1 CAS_COUNT_WR +MBOX1C0 CAS_COUNT_RD +MBOX1C1 CAS_COUNT_WR +MBOX2C0 CAS_COUNT_RD +MBOX2C1 CAS_COUNT_WR +MBOX3C0 CAS_COUNT_RD +MBOX3C1 CAS_COUNT_WR +MBOX4C0 CAS_COUNT_RD +MBOX4C1 CAS_COUNT_WR +MBOX5C0 CAS_COUNT_RD +MBOX5C1 CAS_COUNT_WR +MBOX6C0 CAS_COUNT_RD +MBOX6C1 CAS_COUNT_WR +MBOX7C0 CAS_COUNT_RD +MBOX7C1 CAS_COUNT_WR + + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L2 to L1 load bandwidth [MBytes/s] 1.0E-06*PMC0*64.0/time +L2 to L1 load data volume [GBytes] 1.0E-09*PMC0*64.0 +L1 to L2 evict bandwidth [MBytes/s] 1.0E-06*PMC1*64.0/time +L1 to L2 evict data volume [GBytes] 1.0E-09*PMC1*64.0 +L1 to/from L2 bandwidth [MBytes/s] 1.0E-06*(PMC0+PMC1)*64.0/time +L1 to/from L2 data volume [GBytes] 1.0E-09*(PMC0+PMC1)*64.0 +L3 to L2 load bandwidth [MBytes/s] 1.0E-06*PMC2*64.0/time +L3 to L2 load data volume [GBytes] 1.0E-09*PMC2*64.0 +L2 to L3 evict bandwidth [MBytes/s] 1.0E-06*PMC3*64.0/time +L2 to L3 evict data volume [GBytes] 1.0E-09*PMC3*64.0 +L2 to/from L3 bandwidth [MBytes/s] 1.0E-06*(PMC2+PMC3)*64.0/time +L2 to/from L3 data volume [GBytes] 1.0E-09*(PMC2+PMC3)*64.0 +System to L3 bandwidth [MBytes/s] 1.0E-06*(CBOX0C0+CBOX1C0+CBOX2C0+CBOX3C0+CBOX4C0+CBOX5C0+CBOX6C0+CBOX7C0+CBOX8C0+CBOX9C0+CBOX10C0+CBOX11C0+CBOX12C0+CBOX13C0)*64.0/time +System to L3 data volume [GBytes] 1.0E-09*(CBOX0C0+CBOX1C0+CBOX2C0+CBOX3C0+CBOX4C0+CBOX5C0+CBOX6C0+CBOX7C0+CBOX8C0+CBOX9C0+CBOX10C0+CBOX11C0+CBOX12C0+CBOX13C0)*64.0 +L3 to system bandwidth [MBytes/s] 1.0E-06*(CBOX0C1+CBOX1C1+CBOX2C1+CBOX3C1+CBOX4C1+CBOX5C1+CBOX6C1+CBOX7C1+CBOX8C1+CBOX9C1+CBOX10C1+CBOX11C1+CBOX12C1+CBOX13C1)*64/time +L3 to system data volume [GBytes] 1.0E-09*(CBOX0C1+CBOX1C1+CBOX2C1+CBOX3C1+CBOX4C1+CBOX5C1+CBOX6C1+CBOX7C1+CBOX8C1+CBOX9C1+CBOX10C1+CBOX11C1+CBOX12C1+CBOX13C1)*64 +L3 to/from system bandwidth [MBytes/s] 1.0E-06*(CBOX0C0+CBOX1C0+CBOX2C0+CBOX3C0+CBOX4C0+CBOX5C0+CBOX6C0+CBOX7C0+CBOX8C0+CBOX9C0+CBOX10C0+CBOX11C0+CBOX12C0+CBOX13C0+CBOX0C1+CBOX1C1+CBOX2C1+CBOX3C1+CBOX4C1+CBOX5C1+CBOX6C1+CBOX7C1+CBOX8C1+CBOX9C1+CBOX10C1+CBOX11C1+CBOX12C1+CBOX13C1)*64.0/time +L3 to/from system data volume [GBytes] 1.0E-09*(CBOX0C0+CBOX1C0+CBOX2C0+CBOX3C0+CBOX4C0+CBOX5C0+CBOX6C0+CBOX7C0+CBOX8C0+CBOX9C0+CBOX10C0+CBOX11C0+CBOX12C0+CBOX13C0+CBOX0C1+CBOX1C1+CBOX2C1+CBOX3C1+CBOX4C1+CBOX5C1+CBOX6C1+CBOX7C1+CBOX8C1+CBOX9C1+CBOX10C1+CBOX11C1+CBOX12C1+CBOX13C1)*64.0 +Memory read bandwidth [MBytes/s] 1.0E-06*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX6C0+MBOX7C0)*64.0/time +Memory read data volume [GBytes] 1.0E-09*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX6C0+MBOX7C0)*64.0 +Memory write bandwidth [MBytes/s] 1.0E-06*(MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1+MBOX6C1+MBOX7C1)*64.0/time +Memory write data volume [GBytes] 1.0E-09*(MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1+MBOX6C1+MBOX7C1)*64.0 +Memory bandwidth [MBytes/s] 1.0E-06*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX6C0+MBOX7C0+MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1+MBOX6C1+MBOX7C1)*64.0/time +Memory data volume [GBytes] 1.0E-09*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX6C0+MBOX7C0+MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1+MBOX6C1+MBOX7C1)*64.0 + +LONG +Formulas: +L2 to L1 load bandwidth [MBytes/s] = 1.0E-06*L1D_REPLACEMENT*64/time +L2 to L1 load data volume [GBytes] = 1.0E-09*L1D_REPLACEMENT*64 +L1 to L2 evict bandwidth [MBytes/s] = 1.0E-06*L1D_M_EVICT*64/time +L1 to L2 evict data volume [GBytes] = 1.0E-09*L1D_M_EVICT*64 +L1 to/from L2 bandwidth [MBytes/s] = 1.0E-06*(L1D_REPLACEMENT+L1D_M_EVICT)*64/time +L1 to/from L2 data volume [GBytes] = 1.0E-09*(L1D_REPLACEMENT+L1D_M_EVICT)*64 +L3 to L2 load bandwidth [MBytes/s] = 1.0E-06*L2_LINES_IN_ALL*64/time +L3 to L2 load data volume [GBytes] = 1.0E-09*L2_LINES_IN_ALL*64 +L2 to L3 evict bandwidth [MBytes/s] = 1.0E-06*L2_TRANS_L2_WB*64/time +L2 to L3 evict data volume [GBytes] = 1.0E-09*L2_TRANS_L2_WB*64 +L2 to/from L3 bandwidth [MBytes/s] = 1.0E-06*(L2_LINES_IN_ALL+L2_TRANS_L2_WB)*64/time +L2 to/from L3 data volume [GBytes] = 1.0E-09*(L2_LINES_IN_ALL+L2_TRANS_L2_WB)*64 +System to L3 bandwidth [MBytes/s] = 1.0E-06*(SUM(LLC_LOOKUP_DATA_READ))*64/time +System to L3 data volume [GBytes] = 1.0E-09*(SUM(LLC_LOOKUP_DATA_READ))*64 +L3 to system bandwidth [MBytes/s] = 1.0E-06*(SUM(LLC_VICTIMS_M))*64/time +L3 to system data volume [GBytes] = 1.0E-09*(SUM(LLC_VICTIMS_M))*64 +L3 to/from system bandwidth [MBytes/s] = 1.0E-06*(SUM(LLC_LOOKUP_DATA_READ)+SUM(LLC_VICTIMS_M))*64/time +L3 to/from system data volume [GBytes] = 1.0E-09*(SUM(LLC_LOOKUP_DATA_READ)+SUM(LLC_VICTIMS_M))*64 +Memory read bandwidth [MBytes/s] = 1.0E-06*(SUM(CAS_COUNT_RD))*64.0/time +Memory read data volume [GBytes] = 1.0E-09*(SUM(CAS_COUNT_RD))*64.0 +Memory write bandwidth [MBytes/s] = 1.0E-06*(SUM(CAS_COUNT_WR))*64.0/time +Memory write data volume [GBytes] = 1.0E-09*(SUM(CAS_COUNT_WR))*64.0 +Memory bandwidth [MBytes/s] = 1.0E-06*(SUM(CAS_COUNT_RD)+SUM(CAS_COUNT_WR))*64.0/time +Memory data volume [GBytes] = 1.0E-09*(SUM(CAS_COUNT_RD)+SUM(CAS_COUNT_WR))*64.0 +- +Group to measure cache transfers between L1 and Memory. Please notice that the +L3 to/from system metrics contain any traffic to the system (memory, +Intel QPI, etc.) but don't seem to handle anything because commonly memory read +bandwidth and L3 to L2 bandwidth is higher as the memory to L3 bandwidth. + diff --git a/collectors/likwid/groups/haswellEP/CBOX.txt b/collectors/likwid/groups/haswellEP/CBOX.txt new file mode 100644 index 0000000..d9cc13c --- /dev/null +++ b/collectors/likwid/groups/haswellEP/CBOX.txt @@ -0,0 +1,61 @@ +SHORT CBOX related data and metrics + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +CBOX0C0 LLC_VICTIMS_M +CBOX1C0 LLC_VICTIMS_M +CBOX2C0 LLC_VICTIMS_M +CBOX3C0 LLC_VICTIMS_M +CBOX4C0 LLC_VICTIMS_M +CBOX5C0 LLC_VICTIMS_M +CBOX6C0 LLC_VICTIMS_M +CBOX7C0 LLC_VICTIMS_M +CBOX8C0 LLC_VICTIMS_M +CBOX9C0 LLC_VICTIMS_M +CBOX10C0 LLC_VICTIMS_M +CBOX11C0 LLC_VICTIMS_M +CBOX12C0 LLC_VICTIMS_M +CBOX13C0 LLC_VICTIMS_M +CBOX14C0 LLC_VICTIMS_M +CBOX15C0 LLC_VICTIMS_M +CBOX16C0 LLC_VICTIMS_M +CBOX17C0 LLC_VICTIMS_M +CBOX0C1:STATE=0x1 LLC_LOOKUP_ANY +CBOX1C1:STATE=0x1 LLC_LOOKUP_ANY +CBOX2C1:STATE=0x1 LLC_LOOKUP_ANY +CBOX3C1:STATE=0x1 LLC_LOOKUP_ANY +CBOX4C1:STATE=0x1 LLC_LOOKUP_ANY +CBOX5C1:STATE=0x1 LLC_LOOKUP_ANY +CBOX6C1:STATE=0x1 LLC_LOOKUP_ANY +CBOX7C1:STATE=0x1 LLC_LOOKUP_ANY +CBOX8C1:STATE=0x1 LLC_LOOKUP_ANY +CBOX9C1:STATE=0x1 LLC_LOOKUP_ANY +CBOX10C1:STATE=0x1 LLC_LOOKUP_ANY +CBOX11C1:STATE=0x1 LLC_LOOKUP_ANY +CBOX12C1:STATE=0x1 LLC_LOOKUP_ANY +CBOX13C1:STATE=0x1 LLC_LOOKUP_ANY +CBOX14C1:STATE=0x1 LLC_LOOKUP_ANY +CBOX15C1:STATE=0x1 LLC_LOOKUP_ANY +CBOX16C1:STATE=0x1 LLC_LOOKUP_ANY +CBOX17C1:STATE=0x1 LLC_LOOKUP_ANY + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +LLC misses per instruction (CBOX0C0+CBOX1C0+CBOX2C0+CBOX3C0+CBOX4C0+CBOX5C0+CBOX6C0+CBOX7C0+CBOX8C0+CBOX9C0+CBOX10C0+CBOX11C0+CBOX12C0+CBOX13C0+CBOX14C0+CBOX15C0+CBOX16C0+CBOX17C0)/FIXC0 +LL2 data written to MEM [MBytes] 1E-6*(CBOX0C1:STATE=0x1+CBOX1C1:STATE=0x1+CBOX2C1:STATE=0x1+CBOX3C1:STATE=0x1+CBOX4C1:STATE=0x1+CBOX5C1:STATE=0x1+CBOX6C1:STATE=0x1+CBOX7C1:STATE=0x1+CBOX8C1:STATE=0x1+CBOX9C1:STATE=0x1+CBOX10C1:STATE=0x1+CBOX11C1:STATE=0x1+CBOX12C1:STATE=0x1+CBOX13C1:STATE=0x1+CBOX14C1:STATE=0x1+CBOX15C1:STATE=0x1+CBOX16C1:STATE=0x1+CBOX17C1:STATE=0x1)*64 + + +LONG +Formulas: +LLC Misses Per Instruction = sum(LLC_VICTIMS_M)/INSTR_RETIRED_ANY +LL2 data written to MEM [MBytes] = sum(LLC_LOOKUP_ANY)*64*1E-6 +- +The CBOXes mediate the traffic from the L2 cache to the segmented L3 cache. Each +CBOX is responsible for one segment (2.5 MByte). The boxes maintain the coherence between all +CPU cores of the socket. Depending on the CPU core count, some CBOXes are not attached +to a 2.5 MByte slice but are still active and track the traffic. diff --git a/collectors/likwid/groups/haswellEP/CLOCK.txt b/collectors/likwid/groups/haswellEP/CLOCK.txt new file mode 100644 index 0000000..8055d5b --- /dev/null +++ b/collectors/likwid/groups/haswellEP/CLOCK.txt @@ -0,0 +1,26 @@ +SHORT Power and Energy consumption + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PWR0 PWR_PKG_ENERGY +UBOXFIX UNCORE_CLOCK + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +Uncore Clock [MHz] 1.E-06*UBOXFIX/time +CPI FIXC1/FIXC0 +Energy [J] PWR0 +Power [W] PWR0/time + +LONG +Formulas: +Power = PWR_PKG_ENERGY / time +Uncore Clock [MHz] = 1.E-06 * UNCORE_CLOCK / time +- +Haswell implements the new RAPL interface. This interface enables to +monitor the consumed energy on the package (socket) level. + diff --git a/collectors/likwid/groups/haswellEP/CYCLE_ACTIVITY.txt b/collectors/likwid/groups/haswellEP/CYCLE_ACTIVITY.txt new file mode 100644 index 0000000..c432a44 --- /dev/null +++ b/collectors/likwid/groups/haswellEP/CYCLE_ACTIVITY.txt @@ -0,0 +1,38 @@ +SHORT Cycle Activities + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 CYCLE_ACTIVITY_CYCLES_L2_PENDING +PMC1 CYCLE_ACTIVITY_CYCLES_LDM_PENDING +PMC2 CYCLE_ACTIVITY_CYCLES_L1D_PENDING +PMC3 CYCLE_ACTIVITY_CYCLES_NO_EXECUTE + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Cycles without execution [%] (PMC3/FIXC1)*100 +Cycles without execution due to L1D [%] (PMC2/FIXC1)*100 +Cycles without execution due to L2 [%] (PMC0/FIXC1)*100 +Cycles without execution due to memory loads [%] (PMC1/FIXC1)*100 + +LONG +Formulas: +Cycles without execution [%] = CYCLE_ACTIVITY_CYCLES_NO_EXECUTE/CPU_CLK_UNHALTED_CORE*100 +Cycles with stalls due to L1D [%] = CYCLE_ACTIVITY_CYCLES_L1D_PENDING/CPU_CLK_UNHALTED_CORE*100 +Cycles with stalls due to L2 [%] = CYCLE_ACTIVITY_CYCLES_L2_PENDING/CPU_CLK_UNHALTED_CORE*100 +Cycles without execution due to memory loads [%] = CYCLE_ACTIVITY_CYCLES_LDM_PENDING/CPU_CLK_UNHALTED_CORE*100 +-- +This performance group measures the cycles while waiting for data from the cache +and memory hierarchy. +CYCLE_ACTIVITY_CYCLES_NO_EXECUTE: Counts number of cycles nothing is executed on +any execution port. +CYCLE_ACTIVITY_CYCLES_L1D_PENDING: Cycles while L1 cache miss demand load is +outstanding. +CYCLE_ACTIVITY_CYCLES_L2_PENDING: Cycles while L2 cache miss demand load is +outstanding. +CYCLE_ACTIVITY_CYCLES_LDM_PENDING: Cycles while memory subsystem has an +outstanding load. diff --git a/collectors/likwid/groups/haswellEP/CYCLE_STALLS.txt b/collectors/likwid/groups/haswellEP/CYCLE_STALLS.txt new file mode 100644 index 0000000..795aeb9 --- /dev/null +++ b/collectors/likwid/groups/haswellEP/CYCLE_STALLS.txt @@ -0,0 +1,45 @@ +SHORT Cycle Activities (Stalls) + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 CYCLE_ACTIVITY_STALLS_L2_PENDING +PMC1 CYCLE_ACTIVITY_STALLS_LDM_PENDING +PMC2 CYCLE_ACTIVITY_STALLS_L1D_PENDING +PMC3 CYCLE_ACTIVITY_STALLS_TOTAL + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Total execution stalls PMC3 +Stalls caused by L1D misses [%] (PMC2/PMC3)*100 +Stalls caused by L2 misses [%] (PMC0/PMC3)*100 +Stalls caused by memory loads [%] (PMC1/PMC3)*100 +Execution stall rate [%] (PMC3/FIXC1)*100 +Stalls caused by L1D misses rate [%] (PMC2/FIXC1)*100 +Stalls caused by L2 misses rate [%] (PMC0/FIXC1)*100 +Stalls caused by memory loads rate [%] (PMC1/FIXC1)*100 + +LONG +Formulas: +Total execution stalls = CYCLE_ACTIVITY_STALLS_TOTAL +Stalls caused by L1D misses [%] = (CYCLE_ACTIVITY_STALLS_L1D_PENDING/CYCLE_ACTIVITY_STALLS_TOTAL)*100 +Stalls caused by L2 misses [%] = (CYCLE_ACTIVITY_STALLS_L2_PENDING/CYCLE_ACTIVITY_STALLS_TOTAL)*100 +Stalls caused by memory loads [%] = (CYCLE_ACTIVITY_STALLS_LDM_PENDING/CYCLE_ACTIVITY_STALLS_TOTAL)*100 +Execution stall rate [%] = (CYCLE_ACTIVITY_STALLS_TOTAL/CPU_CLK_UNHALTED_CORE)*100 +Stalls caused by L1D misses rate [%] = (CYCLE_ACTIVITY_STALLS_L1D_PENDING/CPU_CLK_UNHALTED_CORE)*100 +Stalls caused by L2 misses rate [%] = (CYCLE_ACTIVITY_STALLS_L2_PENDING/CPU_CLK_UNHALTED_CORE)*100 +Stalls caused by memory loads rate [%] = (CYCLE_ACTIVITY_STALLS_LDM_PENDING/CPU_CLK_UNHALTED_CORE)*100 +-- +This performance group measures the stalls caused by data traffic in the cache +hierarchy. +CYCLE_ACTIVITY_STALLS_TOTAL: Total execution stalls. +CYCLE_ACTIVITY_STALLS_L1D_PENDING: Execution stalls while L1 cache miss demand +load is outstanding. +CYCLE_ACTIVITY_STALLS_L2_PENDING: Execution stalls while L2 cache miss demand +load is outstanding. +CYCLE_ACTIVITY_STALLS_LDM_PENDING: Execution stalls while memory subsystem has +an outstanding load. diff --git a/collectors/likwid/groups/haswellEP/DATA.txt b/collectors/likwid/groups/haswellEP/DATA.txt new file mode 100644 index 0000000..967cbad --- /dev/null +++ b/collectors/likwid/groups/haswellEP/DATA.txt @@ -0,0 +1,22 @@ +SHORT Load to store ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 MEM_UOPS_RETIRED_LOADS +PMC1 MEM_UOPS_RETIRED_STORES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Load to store ratio PMC0/PMC1 + +LONG +Formulas: +Load to store ratio = MEM_UOPS_RETIRED_LOADS/MEM_UOPS_RETIRED_STORES +- +This is a metric to determine your load to store ratio. + diff --git a/collectors/likwid/groups/haswellEP/DIVIDE.txt b/collectors/likwid/groups/haswellEP/DIVIDE.txt new file mode 100644 index 0000000..c9690cf --- /dev/null +++ b/collectors/likwid/groups/haswellEP/DIVIDE.txt @@ -0,0 +1,24 @@ +SHORT Divide unit information + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 ARITH_DIVIDER_UOPS +PMC1 ARITH_DIVIDER_CYCLES + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Number of divide ops PMC0 +Avg. divide unit usage duration PMC1/PMC0 + +LONG +Formulas: +Number of divide ops = ARITH_DIVIDER_UOPS +Avg. divide unit usage duration = ARITH_DIVIDER_CYCLES/ARITH_DIVIDER_UOPS +- +This performance group measures the average latency of divide operations diff --git a/collectors/likwid/groups/haswellEP/ENERGY.txt b/collectors/likwid/groups/haswellEP/ENERGY.txt new file mode 100644 index 0000000..ee0af1b --- /dev/null +++ b/collectors/likwid/groups/haswellEP/ENERGY.txt @@ -0,0 +1,35 @@ +SHORT Power and Energy consumption + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +TMP0 TEMP_CORE +PWR0 PWR_PKG_ENERGY +PWR1 PWR_PP0_ENERGY +PWR3 PWR_DRAM_ENERGY + + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Temperature [C] TMP0 +Energy [J] PWR0 +Power [W] PWR0/time +Energy PP0 [J] PWR1 +Power PP0 [W] PWR1/time +Energy DRAM [J] PWR3 +Power DRAM [W] PWR3/time + +LONG +Formulas: +Power = PWR_PKG_ENERGY / time +Power PP0 = PWR_PP0_ENERGY / time +Power DRAM = PWR_DRAM_ENERGY / time +- +Haswell implements the new RAPL interface. This interface enables to +monitor the consumed energy on the package (socket) and DRAM level. + diff --git a/collectors/likwid/groups/haswellEP/FALSE_SHARE.txt b/collectors/likwid/groups/haswellEP/FALSE_SHARE.txt new file mode 100644 index 0000000..872dbc1 --- /dev/null +++ b/collectors/likwid/groups/haswellEP/FALSE_SHARE.txt @@ -0,0 +1,34 @@ +SHORT False sharing + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 MEM_LOAD_UOPS_L3_HIT_RETIRED_XSNP_HITM +PMC1 MEM_LOAD_UOPS_L3_MISS_RETIRED_REMOTE_HITM +PMC2 MEM_LOAD_UOPS_RETIRED_ALL_ALL + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Local LLC hit with false sharing [MByte] 1.E-06*PMC0*64 +Local LLC hit with false sharing rate PMC0/PMC2 +Remote LLC false sharing [MByte] 1.E-06*PMC1*64 +Remote LLC false sharing rate PMC1/PMC2 + +LONG +Formulas: +Local LLC false sharing [MByte] = 1.E-06*MEM_LOAD_UOPS_L3_HIT_RETIRED_XSNP_HITM*64 +Local LLC false sharing rate = MEM_LOAD_UOPS_L3_HIT_RETIRED_XSNP_HITM/MEM_LOAD_UOPS_RETIRED_ALL +Remote LLC false sharing [MByte] = 1.E-06*MEM_LOAD_UOPS_L3_MISS_RETIRED_REMOTE_HITM*64 +Remote LLC false sharing rate = MEM_LOAD_UOPS_L3_MISS_RETIRED_REMOTE_HITM/MEM_LOAD_UOPS_RETIRED_ALL +- +False-sharing of cache lines can dramatically reduce the performance of an +application. This performance group measures the L3 traffic induced by false-sharing. +The false-sharing rate uses all memory loads as reference. +For systems with multiple CPU sockets, this performance group also measures the +false-sharing of cache lines over socket boundaries. +Please keep in mind that the MEM_LOAD_UOPS_L3_HIT_RETIRED_XSNP_HITM event may +undercount by as much as 40% (Errata HSW150). diff --git a/collectors/likwid/groups/haswellEP/FLOPS_AVX.txt b/collectors/likwid/groups/haswellEP/FLOPS_AVX.txt new file mode 100644 index 0000000..15aacb8 --- /dev/null +++ b/collectors/likwid/groups/haswellEP/FLOPS_AVX.txt @@ -0,0 +1,28 @@ +SHORT Packed AVX MFLOP/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 AVX_INSTS_CALC + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Packed SP [MFLOP/s] 1.0E-06*(PMC0*8.0)/time +Packed DP [MFLOP/s] 1.0E-06*(PMC0*4.0)/time + +LONG +Formulas: +Packed SP [MFLOP/s] = 1.0E-06*(AVX_INSTS_CALC*8)/runtime +Packed DP [MFLOP/s] = 1.0E-06*(AVX_INSTS_CALC*4)/runtime +- +Packed 32b AVX FLOP/s rates. Approximate counts of AVX & AVX2 256-bit instructions. +May count non-AVX instructions that employ 256-bit operations, including (but +not necessarily limited to) rep string instructions that use 256-bit loads and +stores for optimized performance, XSAVE* and XRSTOR*, and operations that +transition the x87 FPU data registers between x87 and MMX. +Caution: The event AVX_INSTS_CALC counts the insertf128 instruction often used +by the Intel C compilers for (unaligned) vector loads. diff --git a/collectors/likwid/groups/haswellEP/HA.txt b/collectors/likwid/groups/haswellEP/HA.txt new file mode 100644 index 0000000..1e5a700 --- /dev/null +++ b/collectors/likwid/groups/haswellEP/HA.txt @@ -0,0 +1,40 @@ +SHORT Main memory bandwidth in MBytes/s seen from Home agent + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +BBOX0C0 IMC_READS_NORMAL +BBOX0C1 BYPASS_IMC_TAKEN +BBOX0C2 IMC_WRITES_ALL +BBOX1C0 IMC_READS_NORMAL +BBOX1C1 BYPASS_IMC_TAKEN +BBOX1C2 IMC_WRITES_ALL + + + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Memory read bandwidth [MBytes/s] 1.0E-06*(BBOX0C0+BBOX1C0+BBOX0C1+BBOX1C1)*64.0/time +Memory read data volume [GBytes] 1.0E-09*(BBOX0C0+BBOX1C0+BBOX0C1+BBOX1C1)*64.0 +Memory write bandwidth [MBytes/s] 1.0E-06*(BBOX0C2+BBOX1C2)*64.0/time +Memory write data volume [GBytes] 1.0E-09*(BBOX0C2+BBOX1C2)*64.0 +Memory bandwidth [MBytes/s] 1.0E-06*(BBOX0C0+BBOX1C0+BBOX0C1+BBOX1C1+BBOX0C2+BBOX1C2)*64.0/time +Memory data volume [GBytes] 1.0E-09*(BBOX0C0+BBOX1C0+BBOX0C1+BBOX1C1+BBOX0C2+BBOX1C2)*64.0 + +LONG +Formulas: +Memory read bandwidth [MBytes/s] = 1.0E-06*(SUM(IMC_READS_NORMAL)+SUM(BYPASS_IMC_TAKEN))*64.0/time +Memory read data volume [GBytes] = 1.0E-09*(SUM(IMC_READS_NORMAL)+SUM(BYPASS_IMC_TAKEN))*64.0 +Memory write bandwidth [MBytes/s] = 1.0E-06*(SUM(IMC_WRITES_ALL))*64.0/time +Memory write data volume [GBytes] = 1.0E-09*(SUM(IMC_WRITES_ALL))*64.0 +Memory bandwidth [MBytes/s] = 1.0E-06*(SUM(IMC_READS_NORMAL) + SUM(BYPASS_IMC_TAKEN) + SUM(IMC_WRITES_ALL))*64.0/time +Memory data volume [GBytes] = 1.0E-09*(SUM(IMC_READS_NORMAL) + SUM(BYPASS_IMC_TAKEN) + SUM(IMC_WRITES_ALL))*64.0 +- +This group derives the same metrics as the MEM group but use the events of the +Home Agent, a central unit that is responsible for the protocol side of memory +interactions. diff --git a/collectors/likwid/groups/haswellEP/ICACHE.txt b/collectors/likwid/groups/haswellEP/ICACHE.txt new file mode 100644 index 0000000..f1e2335 --- /dev/null +++ b/collectors/likwid/groups/haswellEP/ICACHE.txt @@ -0,0 +1,33 @@ +SHORT Instruction cache miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 ICACHE_ACCESSES +PMC1 ICACHE_MISSES +PMC2 ICACHE_IFETCH_STALL +PMC3 ILD_STALL_IQ_FULL + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L1I request rate PMC0/FIXC0 +L1I miss rate PMC1/FIXC0 +L1I miss ratio PMC1/PMC0 +L1I stalls PMC2 +L1I stall rate PMC2/FIXC0 +L1I queue full stalls PMC3 +L1I queue full stall rate PMC3/FIXC0 + +LONG +Formulas: +L1I request rate = ICACHE_ACCESSES / INSTR_RETIRED_ANY +L1I miss rate = ICACHE_MISSES / INSTR_RETIRED_ANY +L1I miss ratio = ICACHE_MISSES / ICACHE_ACCESSES +L1I stalls = ICACHE_IFETCH_STALL +L1I stall rate = ICACHE_IFETCH_STALL / INSTR_RETIRED_ANY +- +This group measures some L1 instruction cache metrics. diff --git a/collectors/likwid/groups/haswellEP/L2.txt b/collectors/likwid/groups/haswellEP/L2.txt new file mode 100644 index 0000000..60c7f79 --- /dev/null +++ b/collectors/likwid/groups/haswellEP/L2.txt @@ -0,0 +1,37 @@ +SHORT L2 cache bandwidth in MBytes/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 L1D_REPLACEMENT +PMC1 L2_TRANS_L1D_WB +PMC2 ICACHE_MISSES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L2D load bandwidth [MBytes/s] 1.0E-06*PMC0*64.0/time +L2D load data volume [GBytes] 1.0E-09*PMC0*64.0 +L2D evict bandwidth [MBytes/s] 1.0E-06*PMC1*64.0/time +L2D evict data volume [GBytes] 1.0E-09*PMC1*64.0 +L2 bandwidth [MBytes/s] 1.0E-06*(PMC0+PMC1+PMC2)*64.0/time +L2 data volume [GBytes] 1.0E-09*(PMC0+PMC1+PMC2)*64.0 + +LONG +Formulas: +L2D load bandwidth [MBytes/s] = 1.0E-06*L1D_REPLACEMENT*64.0/time +L2D load data volume [GBytes] = 1.0E-09*L1D_REPLACEMENT*64.0 +L2D evict bandwidth [MBytes/s] = 1.0E-06*L2_TRANS_L1D_WB*64.0/time +L2D evict data volume [GBytes] = 1.0E-09*L2_TRANS_L1D_WB*64.0 +L2 bandwidth [MBytes/s] = 1.0E-06*(L1D_REPLACEMENT+L2_TRANS_L1D_WB+ICACHE_MISSES)*64.0/time +L2 data volume [GBytes] = 1.0E-09*(L1D_REPLACEMENT+L2_TRANS_L1D_WB+ICACHE_MISSES)*64.0 +- +Profiling group to measure L2 cache bandwidth. The bandwidth is computed by the +number of cache line loaded from the L2 to the L2 data cache and the writebacks from +the L2 data cache to the L2 cache. The group also outputs total data volume transferred between +L2 and L1. Note that this bandwidth also includes data transfers due to a write +allocate load on a store miss in L1 and cache lines transferred it the instruction +cache. diff --git a/collectors/likwid/groups/haswellEP/L2CACHE.txt b/collectors/likwid/groups/haswellEP/L2CACHE.txt new file mode 100644 index 0000000..9b5dd4b --- /dev/null +++ b/collectors/likwid/groups/haswellEP/L2CACHE.txt @@ -0,0 +1,34 @@ +SHORT L2 cache miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 L2_TRANS_ALL_REQUESTS +PMC1 L2_RQSTS_MISS + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L2 request rate PMC0/FIXC0 +L2 miss rate PMC1/FIXC0 +L2 miss ratio PMC1/PMC0 + +LONG +Formulas: +L2 request rate = L2_TRANS_ALL_REQUESTS/INSTR_RETIRED_ANY +L2 miss rate = L2_RQSTS_MISS/INSTR_RETIRED_ANY +L2 miss ratio = L2_RQSTS_MISS/L2_TRANS_ALL_REQUESTS +- +This group measures the locality of your data accesses with regard to the +L2 cache. L2 request rate tells you how data intensive your code is +or how many data accesses you have on average per instruction. +The L2 miss rate gives a measure how often it was necessary to get +cache lines from memory. And finally L2 miss ratio tells you how many of your +memory references required a cache line to be loaded from a higher level. +While the# data cache miss rate might be given by your algorithm you should +try to get data cache miss ratio as low as possible by increasing your cache reuse. + + diff --git a/collectors/likwid/groups/haswellEP/L3.txt b/collectors/likwid/groups/haswellEP/L3.txt new file mode 100644 index 0000000..0109db3 --- /dev/null +++ b/collectors/likwid/groups/haswellEP/L3.txt @@ -0,0 +1,36 @@ +SHORT L3 cache bandwidth in MBytes/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 L2_LINES_IN_ALL +PMC1 L2_TRANS_L2_WB + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L3 load bandwidth [MBytes/s] 1.0E-06*PMC0*64.0/time +L3 load data volume [GBytes] 1.0E-09*PMC0*64.0 +L3 evict bandwidth [MBytes/s] 1.0E-06*PMC1*64.0/time +L3 evict data volume [GBytes] 1.0E-09*PMC1*64.0 +L3 bandwidth [MBytes/s] 1.0E-06*(PMC0+PMC1)*64.0/time +L3 data volume [GBytes] 1.0E-09*(PMC0+PMC1)*64.0 + +LONG +Formulas: +L3 load bandwidth [MBytes/s] = 1.0E-06*L2_LINES_IN_ALL*64.0/time +L3 load data volume [GBytes] = 1.0E-09*L2_LINES_IN_ALL*64.0 +L3 evict bandwidth [MBytes/s] = 1.0E-06*L2_LINES_OUT_DEMAND_DIRTY*64.0/time +L3 evict data volume [GBytes] = 1.0E-09*L2_LINES_OUT_DEMAND_DIRTY*64.0 +L3 bandwidth [MBytes/s] = 1.0E-06*(L2_LINES_IN_ALL+L2_LINES_OUT_DEMAND_DIRTY)*64/time +L3 data volume [GBytes] = 1.0E-09*(L2_LINES_IN_ALL+L2_LINES_OUT_DEMAND_DIRTY)*64 +- +Profiling group to measure L3 cache bandwidth. The bandwidth is computed by the +number of cache line allocated in the L2 and the number of modified cache lines +evicted from the L2. This group also output data volume transferred between the +L3 and measured cores L2 caches. Note that this bandwidth also includes data +transfers due to a write allocate load on a store miss in L2. + diff --git a/collectors/likwid/groups/haswellEP/L3CACHE.txt b/collectors/likwid/groups/haswellEP/L3CACHE.txt new file mode 100644 index 0000000..f863daa --- /dev/null +++ b/collectors/likwid/groups/haswellEP/L3CACHE.txt @@ -0,0 +1,35 @@ +SHORT L3 cache miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 MEM_LOAD_UOPS_RETIRED_L3_ALL +PMC1 MEM_LOAD_UOPS_RETIRED_L3_MISS +PMC2 UOPS_RETIRED_ALL + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L3 request rate PMC0/PMC2 +L3 miss rate PMC1/PMC2 +L3 miss ratio PMC1/PMC0 + +LONG +Formulas: +L3 request rate = MEM_LOAD_UOPS_RETIRED_L3_ALL/UOPS_RETIRED_ALL +L3 miss rate = MEM_LOAD_UOPS_RETIRED_L3_MISS/UOPS_RETIRED_ALL +L3 miss ratio = MEM_LOAD_UOPS_RETIRED_L3_MISS/MEM_LOAD_UOPS_RETIRED_L3_ALL +- +This group measures the locality of your data accesses with regard to the +L3 cache. L3 request rate tells you how data intensive your code is +or how many data accesses you have on average per instruction. +The L3 miss rate gives a measure how often it was necessary to get +cache lines from memory. And finally L3 miss ratio tells you how many of your +memory references required a cache line to be loaded from a higher level. +While the# data cache miss rate might be given by your algorithm you should +try to get data cache miss ratio as low as possible by increasing your cache reuse. + + diff --git a/collectors/likwid/groups/haswellEP/MEM.txt b/collectors/likwid/groups/haswellEP/MEM.txt new file mode 100644 index 0000000..2a17a2c --- /dev/null +++ b/collectors/likwid/groups/haswellEP/MEM.txt @@ -0,0 +1,52 @@ +SHORT Main memory bandwidth in MBytes/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +MBOX0C0 CAS_COUNT_RD +MBOX0C1 CAS_COUNT_WR +MBOX1C0 CAS_COUNT_RD +MBOX1C1 CAS_COUNT_WR +MBOX2C0 CAS_COUNT_RD +MBOX2C1 CAS_COUNT_WR +MBOX3C0 CAS_COUNT_RD +MBOX3C1 CAS_COUNT_WR +MBOX4C0 CAS_COUNT_RD +MBOX4C1 CAS_COUNT_WR +MBOX5C0 CAS_COUNT_RD +MBOX5C1 CAS_COUNT_WR +MBOX6C0 CAS_COUNT_RD +MBOX6C1 CAS_COUNT_WR +MBOX7C0 CAS_COUNT_RD +MBOX7C1 CAS_COUNT_WR + + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Memory read bandwidth [MBytes/s] 1.0E-06*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX6C0+MBOX7C0)*64.0/time +Memory read data volume [GBytes] 1.0E-09*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX6C0+MBOX7C0)*64.0 +Memory write bandwidth [MBytes/s] 1.0E-06*(MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1+MBOX6C1+MBOX7C1)*64.0/time +Memory write data volume [GBytes] 1.0E-09*(MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1+MBOX6C1+MBOX7C1)*64.0 +Memory bandwidth [MBytes/s] 1.0E-06*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX6C0+MBOX7C0+MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1+MBOX6C1+MBOX7C1)*64.0/time +Memory data volume [GBytes] 1.0E-09*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX6C0+MBOX7C0+MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1+MBOX6C1+MBOX7C1)*64.0 + +LONG +Formulas: +Memory read bandwidth [MBytes/s] = 1.0E-06*(SUM(MBOXxC0))*64.0/runtime +Memory read data volume [GBytes] = 1.0E-09*(SUM(MBOXxC0))*64.0 +Memory write bandwidth [MBytes/s] = 1.0E-06*(SUM(MBOXxC1))*64.0/runtime +Memory write data volume [GBytes] = 1.0E-09*(SUM(MBOXxC1))*64.0 +Memory bandwidth [MBytes/s] = 1.0E-06*(SUM(MBOXxC0)+SUM(MBOXxC1))*64.0/runtime +Memory data volume [GBytes] = 1.0E-09*(SUM(MBOXxC0)+SUM(MBOXxC1))*64.0 +- +Profiling group to measure memory bandwidth drawn by all cores of a socket. +Since this group is based on Uncore events it is only possible to measure on a +per socket base. Some of the counters may not be available on your system. +Also outputs total data volume transferred from main memory. +The same metrics are provided by the HA group. + diff --git a/collectors/likwid/groups/haswellEP/NUMA.txt b/collectors/likwid/groups/haswellEP/NUMA.txt new file mode 100644 index 0000000..41fbe62 --- /dev/null +++ b/collectors/likwid/groups/haswellEP/NUMA.txt @@ -0,0 +1,33 @@ +SHORT Local and remote memory accesses + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 OFFCORE_RESPONSE_0_LOCAL_DRAM +PMC1 OFFCORE_RESPONSE_1_REMOTE_DRAM + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Local DRAM data volume [GByte] 1.E-09*PMC0*64 +Local DRAM bandwidth [MByte/s] 1.E-06*(PMC0*64)/time +Remote DRAM data volume [GByte] 1.E-09*PMC1*64 +Remote DRAM bandwidth [MByte/s] 1.E-06*(PMC1*64)/time +Memory data volume [GByte] 1.E-09*(PMC0+PMC1)*64 +Memory bandwidth [MByte/s] 1.E-06*((PMC0+PMC1)*64)/time + +LONG +Formulas: +CPI = CPU_CLK_UNHALTED_CORE/INSTR_RETIRED_ANY +Local DRAM data volume [GByte] = 1.E-09*OFFCORE_RESPONSE_0_LOCAL_DRAM*64 +Local DRAM bandwidth [MByte/s] = 1.E-06*(OFFCORE_RESPONSE_0_LOCAL_DRAM*64)/time +Remote DRAM data volume [GByte] = 1.E-09*OFFCORE_RESPONSE_1_REMOTE_DRAM*64 +Remote DRAM bandwidth [MByte/s] = 1.E-06*(OFFCORE_RESPONSE_1_REMOTE_DRAM*64)/time +Memory data volume [GByte] = 1.E-09*(OFFCORE_RESPONSE_0_LOCAL_DRAM+OFFCORE_RESPONSE_1_REMOTE_DRAM)*64 +Memory bandwidth [MByte/s] = 1.E-06*((OFFCORE_RESPONSE_0_LOCAL_DRAM+OFFCORE_RESPONSE_1_REMOTE_DRAM)*64)/time +-- +This performance group measures the data traffic of CPU cores to local and remote +memory. diff --git a/collectors/likwid/groups/haswellEP/PORT_USAGE.txt b/collectors/likwid/groups/haswellEP/PORT_USAGE.txt new file mode 100644 index 0000000..eb74ffe --- /dev/null +++ b/collectors/likwid/groups/haswellEP/PORT_USAGE.txt @@ -0,0 +1,46 @@ +SHORT Execution port utilization + +REQUIRE_NOHT + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 UOPS_EXECUTED_PORT_PORT_0 +PMC1 UOPS_EXECUTED_PORT_PORT_1 +PMC2 UOPS_EXECUTED_PORT_PORT_2 +PMC3 UOPS_EXECUTED_PORT_PORT_3 +PMC4 UOPS_EXECUTED_PORT_PORT_4 +PMC5 UOPS_EXECUTED_PORT_PORT_5 +PMC6 UOPS_EXECUTED_PORT_PORT_6 +PMC7 UOPS_EXECUTED_PORT_PORT_7 + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Port0 usage ratio PMC0/(PMC0+PMC1+PMC2+PMC3+PMC4+PMC5+PMC6+PMC7) +Port1 usage ratio PMC1/(PMC0+PMC1+PMC2+PMC3+PMC4+PMC5+PMC6+PMC7) +Port2 usage ratio PMC2/(PMC0+PMC1+PMC2+PMC3+PMC4+PMC5+PMC6+PMC7) +Port3 usage ratio PMC3/(PMC0+PMC1+PMC2+PMC3+PMC4+PMC5+PMC6+PMC7) +Port4 usage ratio PMC4/(PMC0+PMC1+PMC2+PMC3+PMC4+PMC5+PMC6+PMC7) +Port5 usage ratio PMC5/(PMC0+PMC1+PMC2+PMC3+PMC4+PMC5+PMC6+PMC7) +Port6 usage ratio PMC6/(PMC0+PMC1+PMC2+PMC3+PMC4+PMC5+PMC6+PMC7) +Port7 usage ratio PMC7/(PMC0+PMC1+PMC2+PMC3+PMC4+PMC5+PMC6+PMC7) + +LONG +Formulas: +Port0 usage ratio = UOPS_EXECUTED_PORT_PORT_0/SUM(UOPS_EXECUTED_PORT_PORT_*) +Port1 usage ratio = UOPS_EXECUTED_PORT_PORT_1/SUM(UOPS_EXECUTED_PORT_PORT_*) +Port2 usage ratio = UOPS_EXECUTED_PORT_PORT_2/SUM(UOPS_EXECUTED_PORT_PORT_*) +Port3 usage ratio = UOPS_EXECUTED_PORT_PORT_3/SUM(UOPS_EXECUTED_PORT_PORT_*) +Port4 usage ratio = UOPS_EXECUTED_PORT_PORT_4/SUM(UOPS_EXECUTED_PORT_PORT_*) +Port5 usage ratio = UOPS_EXECUTED_PORT_PORT_5/SUM(UOPS_EXECUTED_PORT_PORT_*) +Port6 usage ratio = UOPS_EXECUTED_PORT_PORT_6/SUM(UOPS_EXECUTED_PORT_PORT_*) +Port7 usage ratio = UOPS_EXECUTED_PORT_PORT_7/SUM(UOPS_EXECUTED_PORT_PORT_*) +- +This group measures the execution port utilization in a CPU core. The group can +only be measured when HyperThreading is disabled because only then each CPU core +can program eight counters. diff --git a/collectors/likwid/groups/haswellEP/QPI.txt b/collectors/likwid/groups/haswellEP/QPI.txt new file mode 100644 index 0000000..dcdda85 --- /dev/null +++ b/collectors/likwid/groups/haswellEP/QPI.txt @@ -0,0 +1,49 @@ +SHORT QPI Link Layer data + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +QBOX0C0 RXL_FLITS_G0_DATA +QBOX1C0 RXL_FLITS_G0_DATA +QBOX0C1 RXL_FLITS_G0_NON_DATA +QBOX1C1 RXL_FLITS_G0_NON_DATA +QBOX0C2 TXL_FLITS_G0_DATA +QBOX1C2 TXL_FLITS_G0_DATA +QBOX0C3 TXL_FLITS_G0_NON_DATA +QBOX1C3 TXL_FLITS_G0_NON_DATA + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +QPI send data volume [GByte] 1.E-09*(QBOX0C2+QBOX1C2)*8 +QPI send data bandwidth [MByte/s] 1.E-06*(QBOX0C2+QBOX1C2)*8/time +QPI send link volume [GByte] 1.E-09*(QBOX0C2+QBOX1C2+QBOX0C3+QBOX1C3)*8 +QPI send link bandwidth [MByte/s] 1.E-06*(QBOX0C2+QBOX1C2+QBOX0C3+QBOX1C3)*8/time +QPI receive data volume [GByte] 1.E-09*(QBOX0C0+QBOX1C0)*8 +QPI receive data bandwidth [MByte/s] 1.E-06*(QBOX0C0+QBOX1C0)*8/time +QPI receive link volume [GByte] 1.E-09*(QBOX0C0+QBOX1C0+QBOX0C1+QBOX1C1)*8 +QPI receive link bandwidth [MByte/s] 1.E-06*(QBOX0C0+QBOX1C0+QBOX0C1+QBOX1C1)*8/time +QPI total transfer volume [GByte] 1.E-09*(QBOX0C0+QBOX1C0+QBOX0C2+QBOX1C2+QBOX0C1+QBOX1C1+QBOX0C3+QBOX1C3)*8 +QPI total bandwidth [MByte/s] 1.E-06*(QBOX0C0+QBOX1C0+QBOX0C2+QBOX1C2+QBOX0C1+QBOX1C1+QBOX0C3+QBOX1C3)*8/time + +LONG +Formulas: +QPI send data volume [GByte] = 1.E-09*(sum(TXL_FLITS_G0_DATA)*8) +QPI send data bandwidth [MByte/s] = 1.E-06*(sum(TXL_FLITS_G0_DATA)*8)/runtime +QPI send link volume [GByte] = 1.E-09*((sum(TXL_FLITS_G0_DATA)+sum(TXL_FLITS_G0_NON_DATA))*8) +QPI send link bandwidth [MByte/s] = 1.E-06*((sum(TXL_FLITS_G0_DATA)+sum(TXL_FLITS_G0_NON_DATA))*8)/runtime +QPI receive data volume [GByte] = 1.E-09*(sum(RXL_FLITS_G0_DATA)*8) +QPI receive data bandwidth [MByte/s] = 1.E-06*(sum(RXL_FLITS_G0_DATA)*8)/runtime +QPI receive link volume [GByte] = 1.E-09*((sum(RXL_FLITS_G0_DATA)+sum(RXL_FLITS_G0_NON_DATA))*8) +QPI receive link bandwidth [MByte/s] = 1.E-06*((sum(RXL_FLITS_G0_DATA)+sum(RXL_FLITS_G0_NON_DATA))*8)/runtime +QPI total transfer volume [GByte] = 1.E-09*(sum(TXL_FLITS_G0_DATA)+sum(TXL_FLITS_G0_NON_DATA)+sum(RXL_FLITS_G0_DATA)+sum(RXL_FLITS_G0_NON_DATA))*8 +QPI total bandwidth [MByte/s] = 1.E-06*(sum(TXL_FLITS_G0_DATA)+sum(TXL_FLITS_G0_NON_DATA)+sum(RXL_FLITS_G0_DATA)+sum(RXL_FLITS_G0_NON_DATA))*8/time +-- +The Intel QPI Link Layer is responsible for packetizing requests from the caching agent (CBOXes) +on the way out to the system interface. For Haswell EP systems, the Link Layer and the +Ring interface is separated. The QPI link volume contains header, data and trailer while the +QPI data volume counts only the data flits. diff --git a/collectors/likwid/groups/haswellEP/RECOVERY.txt b/collectors/likwid/groups/haswellEP/RECOVERY.txt new file mode 100644 index 0000000..7928ee4 --- /dev/null +++ b/collectors/likwid/groups/haswellEP/RECOVERY.txt @@ -0,0 +1,22 @@ +SHORT Recovery duration + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 INT_MISC_RECOVERY_CYCLES +PMC1 INT_MISC_RECOVERY_COUNT + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Avg. recovery duration PMC0/PMC1 + +LONG +Formulas: +Avg. recovery duration = INT_MISC_RECOVERY_CYCLES/INT_MISC_RECOVERY_COUNT +- +This group measures the duration of recoveries after SSE exception, memory +disambiguation, etc... diff --git a/collectors/likwid/groups/haswellEP/SBOX.txt b/collectors/likwid/groups/haswellEP/SBOX.txt new file mode 100644 index 0000000..24f86b6 --- /dev/null +++ b/collectors/likwid/groups/haswellEP/SBOX.txt @@ -0,0 +1,28 @@ +SHORT Ring Transfer bandwidth + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +SBOX0C0 RING_BL_USED_ANY +SBOX1C0 RING_BL_USED_ANY +SBOX2C0 RING_BL_USED_ANY +SBOX3C0 RING_BL_USED_ANY + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Ring transfer bandwidth [MByte/s] 1.E-06*(SBOX0C0+SBOX1C0+SBOX2C0+SBOX3C0)*32/time +Ring transfer data volume [GByte] 1.E-09*(SBOX0C0+SBOX1C0+SBOX2C0+SBOX3C0)*32 + +LONG +Formulas: +Ring transfer bandwidth [MByte/s] = 1.E-06*(SUM(SBOXxC0)*32)/time +Ring transfer data volume [GByte] = 1.E-09*(SUM(SBOXxC0)*32) +-- +The SBOXes manage the transfer between the socket local ring(s). For micro architectures +prior to Haswell, the SBOX and QBOX was similar as only a single ring was used. +Haswell systems with a high core count assemble two rings that are connected through +the SBOXes, the traffic between the sockets is handled by the QBOXes. diff --git a/collectors/likwid/groups/haswellEP/TLB_DATA.txt b/collectors/likwid/groups/haswellEP/TLB_DATA.txt new file mode 100644 index 0000000..8d94e05 --- /dev/null +++ b/collectors/likwid/groups/haswellEP/TLB_DATA.txt @@ -0,0 +1,35 @@ +SHORT L2 data TLB miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 DTLB_LOAD_MISSES_CAUSES_A_WALK +PMC1 DTLB_STORE_MISSES_CAUSES_A_WALK +PMC2 DTLB_LOAD_MISSES_WALK_DURATION +PMC3 DTLB_STORE_MISSES_WALK_DURATION + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L1 DTLB load misses PMC0 +L1 DTLB load miss rate PMC0/FIXC0 +L1 DTLB load miss duration [Cyc] PMC2/PMC0 +L1 DTLB store misses PMC1 +L1 DTLB store miss rate PMC1/FIXC0 +L1 DTLB store miss duration [Cyc] PMC3/PMC1 + +LONG +Formulas: +L1 DTLB load misses = DTLB_LOAD_MISSES_CAUSES_A_WALK +L1 DTLB load miss rate = DTLB_LOAD_MISSES_CAUSES_A_WALK / INSTR_RETIRED_ANY +L1 DTLB load miss duration [Cyc] = DTLB_LOAD_MISSES_WALK_DURATION / DTLB_LOAD_MISSES_CAUSES_A_WALK +L1 DTLB store misses = DTLB_STORE_MISSES_CAUSES_A_WALK +L1 DTLB store miss rate = DTLB_STORE_MISSES_CAUSES_A_WALK / INSTR_RETIRED_ANY +L1 DTLB store miss duration [Cyc] = DTLB_STORE_MISSES_WALK_DURATION / DTLB_STORE_MISSES_CAUSES_A_WALK +- +The DTLB load and store miss rates gives a measure how often a TLB miss occurred +per instruction. The duration measures the time in cycles how long a walk did take. + diff --git a/collectors/likwid/groups/haswellEP/TLB_INSTR.txt b/collectors/likwid/groups/haswellEP/TLB_INSTR.txt new file mode 100644 index 0000000..235d977 --- /dev/null +++ b/collectors/likwid/groups/haswellEP/TLB_INSTR.txt @@ -0,0 +1,28 @@ +SHORT L1 Instruction TLB miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 ITLB_MISSES_CAUSES_A_WALK +PMC1 ITLB_MISSES_WALK_DURATION + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L1 ITLB misses PMC0 +L1 ITLB miss rate PMC0/FIXC0 +L1 ITLB miss duration [Cyc] PMC1/PMC0 + + +LONG +Formulas: +L1 ITLB misses = ITLB_MISSES_CAUSES_A_WALK +L1 ITLB miss rate = ITLB_MISSES_CAUSES_A_WALK / INSTR_RETIRED_ANY +L1 ITLB miss duration [Cyc] = ITLB_MISSES_WALK_DURATION / ITLB_MISSES_CAUSES_A_WALK +- +The ITLB miss rates gives a measure how often a TLB miss occurred +per instruction. The duration measures the time in cycles how long a walk did take. + diff --git a/collectors/likwid/groups/haswellEP/TMA.txt b/collectors/likwid/groups/haswellEP/TMA.txt new file mode 100644 index 0000000..afb4126 --- /dev/null +++ b/collectors/likwid/groups/haswellEP/TMA.txt @@ -0,0 +1,48 @@ +SHORT Top down cycle allocation + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 UOPS_ISSUED_ANY +PMC1 UOPS_RETIRED_RETIRE_SLOTS +PMC2 IDQ_UOPS_NOT_DELIVERED_CORE +PMC3 INT_MISC_RECOVERY_CYCLES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +IPC FIXC0/FIXC1 +Total Slots 4*FIXC1 +Slots Retired PMC1 +Fetch Bubbles PMC2 +Recovery Bubbles 4*PMC3 +Front End [%] PMC2/(4*FIXC1)*100 +Speculation [%] (PMC0-PMC1+(4*PMC3))/(4*FIXC1)*100 +Retiring [%] PMC1/(4*FIXC1)*100 +Back End [%] (1-((PMC2+PMC0+(4*PMC3))/(4*FIXC1)))*100 + +LONG +Formulas: +Total Slots = 4*CPU_CLK_UNHALTED_CORE +Slots Retired = UOPS_RETIRED_RETIRE_SLOTS +Fetch Bubbles = IDQ_UOPS_NOT_DELIVERED_CORE +Recovery Bubbles = 4*INT_MISC_RECOVERY_CYCLES +Front End [%] = IDQ_UOPS_NOT_DELIVERED_CORE/(4*CPU_CLK_UNHALTED_CORE)*100 +Speculation [%] = (UOPS_ISSUED_ANY-UOPS_RETIRED_RETIRE_SLOTS+(4*INT_MISC_RECOVERY_CYCLES))/(4*CPU_CLK_UNHALTED_CORE)*100 +Retiring [%] = UOPS_RETIRED_RETIRE_SLOTS/(4*CPU_CLK_UNHALTED_CORE)*100 +Back End [%] = (1-((IDQ_UOPS_NOT_DELIVERED_CORE+UOPS_ISSUED_ANY+(4*INT_MISC_RECOVERY_CYCLES))/(4*CPU_CLK_UNHALTED_CORE)))*100 +-- +This performance group measures cycles to determine percentage of time spent in +front end, back end, retiring and speculation. These metrics are published and +verified by Intel. Further information: +Webpage describing Top-Down Method and its usage in Intel vTune: +https://software.intel.com/en-us/vtune-amplifier-help-tuning-applications-using-a-top-down-microarchitecture-analysis-method +Paper by Yasin Ahmad: +https://sites.google.com/site/analysismethods/yasin-pubs/TopDown-Yasin-ISPASS14.pdf?attredirects=0 +Slides by Yasin Ahmad: +http://www.cs.technion.ac.il/~erangi/TMA_using_Linux_perf__Ahmad_Yasin.pdf +The performance group was originally published here: +http://perf.mvermeulen.com/2018/04/14/top-down-performance-counter-analysis-part-1-likwid/ diff --git a/collectors/likwid/groups/haswellEP/UOPS.txt b/collectors/likwid/groups/haswellEP/UOPS.txt new file mode 100644 index 0000000..e6cc208 --- /dev/null +++ b/collectors/likwid/groups/haswellEP/UOPS.txt @@ -0,0 +1,35 @@ +SHORT UOPs execution info + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 UOPS_ISSUED_ANY +PMC1 UOPS_EXECUTED_THREAD +PMC2 UOPS_RETIRED_ALL +PMC3 UOPS_ISSUED_FLAGS_MERGE + + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Issued UOPs PMC0 +Merged UOPs PMC3 +Executed UOPs PMC1 +Retired UOPs PMC2 + +LONG +Formulas: +Issued UOPs = UOPS_ISSUED_ANY +Merged UOPs = UOPS_ISSUED_FLAGS_MERGE +Executed UOPs = UOPS_EXECUTED_THREAD +Retired UOPs = UOPS_RETIRED_ALL +- +This group returns information about the instruction pipeline. It measures the +issued, executed and retired uOPs and returns the number of uOPs which were issued +but not executed as well as the number of uOPs which were executed but never retired. +The executed but not retired uOPs commonly come from speculatively executed branches. + diff --git a/collectors/likwid/groups/haswellEP/UOPS_EXEC.txt b/collectors/likwid/groups/haswellEP/UOPS_EXEC.txt new file mode 100644 index 0000000..7042df7 --- /dev/null +++ b/collectors/likwid/groups/haswellEP/UOPS_EXEC.txt @@ -0,0 +1,31 @@ +SHORT UOPs execution + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 UOPS_EXECUTED_USED_CYCLES +PMC1 UOPS_EXECUTED_STALL_CYCLES +PMC2 CPU_CLOCK_UNHALTED_TOTAL_CYCLES +PMC3:EDGEDETECT UOPS_EXECUTED_STALL_CYCLES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Used cycles ratio [%] 100*PMC0/PMC2 +Unused cycles ratio [%] 100*PMC1/PMC2 +Avg stall duration [cycles] PMC1/PMC3:EDGEDETECT + + +LONG +Formulas: +Used cycles ratio [%] = 100*UOPS_EXECUTED_USED_CYCLES/CPU_CLK_UNHALTED_CORE +Unused cycles ratio [%] = 100*UOPS_EXECUTED_STALL_CYCLES/CPU_CLK_UNHALTED_CORE +Avg stall duration [cycles] = UOPS_EXECUTED_STALL_CYCLES/UOPS_EXECUTED_STALL_CYCLES:EDGEDETECT +- +This performance group returns the ratios of used and unused cycles regarding +the execution stage in the pipeline. Used cycles are all cycles where uOPs are +executed while unused cycles refer to pipeline stalls. Moreover, the group +calculates the average stall duration in cycles. diff --git a/collectors/likwid/groups/haswellEP/UOPS_ISSUE.txt b/collectors/likwid/groups/haswellEP/UOPS_ISSUE.txt new file mode 100644 index 0000000..9aac923 --- /dev/null +++ b/collectors/likwid/groups/haswellEP/UOPS_ISSUE.txt @@ -0,0 +1,31 @@ +SHORT UOPs issueing + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 UOPS_ISSUED_USED_CYCLES +PMC1 UOPS_ISSUED_STALL_CYCLES +PMC2 CPU_CLOCK_UNHALTED_TOTAL_CYCLES +PMC3:EDGEDETECT UOPS_ISSUED_STALL_CYCLES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Used cycles ratio [%] 100*PMC0/PMC2 +Unused cycles ratio [%] 100*PMC1/PMC2 +Avg stall duration [cycles] PMC1/PMC3:EDGEDETECT + + +LONG +Formulas: +Used cycles ratio [%] = 100*UOPS_ISSUED_USED_CYCLES/CPU_CLK_UNHALTED_CORE +Unused cycles ratio [%] = 100*UOPS_ISSUED_STALL_CYCLES/CPU_CLK_UNHALTED_CORE +Avg stall duration [cycles] = UOPS_ISSUED_STALL_CYCLES/UOPS_ISSUED_STALL_CYCLES:EDGEDETECT +- +This performance group returns the ratios of used and unused cycles regarding +the issue stage in the pipeline. Used cycles are all cycles where uOPs are +issued while unused cycles refer to pipeline stalls. Moreover, the group +calculates the average stall duration in cycles. diff --git a/collectors/likwid/groups/haswellEP/UOPS_RETIRE.txt b/collectors/likwid/groups/haswellEP/UOPS_RETIRE.txt new file mode 100644 index 0000000..0f37585 --- /dev/null +++ b/collectors/likwid/groups/haswellEP/UOPS_RETIRE.txt @@ -0,0 +1,31 @@ +SHORT UOPs retirement + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 UOPS_RETIRED_USED_CYCLES +PMC1 UOPS_RETIRED_STALL_CYCLES +PMC2 CPU_CLOCK_UNHALTED_TOTAL_CYCLES +PMC3:EDGEDETECT UOPS_RETIRED_STALL_CYCLES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Used cycles ratio [%] 100*PMC0/PMC2 +Unused cycles ratio [%] 100*PMC1/PMC2 +Avg stall duration [cycles] PMC1/PMC3:EDGEDETECT + + +LONG +Formulas: +Used cycles ratio [%] = 100*UOPS_RETIRED_USED_CYCLES/CPU_CLK_UNHALTED_CORE +Unused cycles ratio [%] = 100*UOPS_RETIRED_STALL_CYCLES/CPU_CLK_UNHALTED_CORE +Avg stall duration [cycles] = UOPS_RETIRED_STALL_CYCLES/UOPS_RETIRED_STALL_CYCLES:EDGEDETECT +- +This performance group returns the ratios of used and unused cycles regarding +the retirement stage in the pipeline (re-order buffer). Used cycles are all +cycles where uOPs are retired while unused cycles refer to pipeline stalls. +Moreover, the group calculates the average stall duration in cycles. diff --git a/collectors/likwid/groups/interlagos/BRANCH.txt b/collectors/likwid/groups/interlagos/BRANCH.txt new file mode 100644 index 0000000..7495b74 --- /dev/null +++ b/collectors/likwid/groups/interlagos/BRANCH.txt @@ -0,0 +1,26 @@ +SHORT Branch prediction miss rate/ratio + +EVENTSET +PMC0 RETIRED_INSTRUCTIONS +PMC1 RETIRED_BRANCH_INSTR +PMC2 RETIRED_MISPREDICTED_BRANCH_INSTR + +METRICS +Runtime (RDTSC) [s] time +Branch rate PMC1/PMC0 +Branch misprediction rate PMC2/PMC0 +Branch misprediction ratio PMC2/PMC1 +Instructions per branch PMC0/PMC1 + +LONG +Formulas: +Branch rate = RETIRED_BRANCH_INSTR/RETIRED_INSTRUCTIONS +Branch misprediction rate = RETIRED_MISPREDICTED_BRANCH_INSTR/RETIRED_INSTRUCTIONS +Branch misprediction ratio = RETIRED_MISPREDICTED_BRANCH_INSTR/RETIRED_BRANCH_INSTR +Instructions per branch = RETIRED_INSTRUCTIONS/RETIRED_BRANCH_INSTR +- +The rates state how often on average a branch or a mispredicted branch occurred +per instruction retired in total. The branch misprediction ratio sets directly +into relation what ratio of all branch instruction where mispredicted. +Instructions per branch is 1/branch rate. + diff --git a/collectors/likwid/groups/interlagos/CACHE.txt b/collectors/likwid/groups/interlagos/CACHE.txt new file mode 100644 index 0000000..0d785fc --- /dev/null +++ b/collectors/likwid/groups/interlagos/CACHE.txt @@ -0,0 +1,32 @@ +SHORT Data cache miss rate/ratio + +EVENTSET +PMC0 RETIRED_INSTRUCTIONS +PMC1 DATA_CACHE_ACCESSES +PMC2 DATA_CACHE_REFILLS_VALID +PMC3 DATA_CACHE_MISSES_ALL + +METRICS +Runtime (RDTSC) [s] time +data cache misses PMC3 +data cache request rate PMC1/PMC0 +data cache miss rate (PMC2)/PMC0 +data cache miss ratio (PMC2)/PMC1 + +LONG +Formulas: +data cache misses = DATA_CACHE_MISSES_ALL +data cache request rate = DATA_CACHE_ACCESSES / RETIRED_INSTRUCTIONS +data cache miss rate = (DATA_CACHE_REFILLS_VALID) / RETIRED_INSTRUCTIONS +data cache miss ratio = (DATA_CACHE_REFILLS_VALID)/DATA_CACHE_ACCESSES +- +This group measures the locality of your data accesses with regard to the +L1 cache. Data cache request rate tells you how data intensive your code is +or how many data accesses you have on average per instruction. +The data cache miss rate gives a measure how often it was necessary to get +cache lines from higher levels of the memory hierarchy. And finally +data cache miss ratio tells you how many of your memory references required +a cache line to be loaded from a higher level. While the# data cache miss rate +might be given by your algorithm you should try to get data cache miss ratio +as low as possible by increasing your cache reuse. + diff --git a/collectors/likwid/groups/interlagos/CPI.txt b/collectors/likwid/groups/interlagos/CPI.txt new file mode 100644 index 0000000..c0746e7 --- /dev/null +++ b/collectors/likwid/groups/interlagos/CPI.txt @@ -0,0 +1,26 @@ +SHORT Cycles per instruction + +EVENTSET +PMC0 RETIRED_INSTRUCTIONS +PMC1 CPU_CLOCKS_UNHALTED +PMC2 RETIRED_UOPS + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] PMC1*inverseClock +CPI PMC1/PMC0 +CPI (based on uops) PMC1/PMC2 +IPC PMC0/PMC1 + +LONG +Formulas: +CPI = CPU_CLOCKS_UNHALTED/RETIRED_INSTRUCTIONS +CPI (based on uops) = CPU_CLOCKS_UNHALTED/RETIRED_UOPS +IPC = RETIRED_INSTRUCTIONS/CPU_CLOCKS_UNHALTED +- +This group measures how efficient the processor works with +regard to instruction throughput. Also important as a standalone +metric is RETIRED_INSTRUCTIONS as it tells you how many instruction +you need to execute for a task. An optimization might show very +low CPI values but execute many more instruction for it. + diff --git a/collectors/likwid/groups/interlagos/DATA.txt b/collectors/likwid/groups/interlagos/DATA.txt new file mode 100644 index 0000000..75f1f60 --- /dev/null +++ b/collectors/likwid/groups/interlagos/DATA.txt @@ -0,0 +1,16 @@ +SHORT Load to store ratio + +EVENTSET +PMC0 LS_DISPATCH_LOADS +PMC1 LS_DISPATCH_STORES + +METRICS +Runtime (RDTSC) [s] time +Load to store ratio PMC0/PMC1 + +LONG +Formulas: +Load to store ratio = LS_DISPATCH_LOADS/LS_DISPATCH_STORES +- +This is a simple metric to determine your load to store ratio. + diff --git a/collectors/likwid/groups/interlagos/FLOPS_DP.txt b/collectors/likwid/groups/interlagos/FLOPS_DP.txt new file mode 100644 index 0000000..7af248c --- /dev/null +++ b/collectors/likwid/groups/interlagos/FLOPS_DP.txt @@ -0,0 +1,23 @@ +SHORT Double Precision MFLOP/s + +EVENTSET +PMC0 RETIRED_INSTRUCTIONS +PMC1 CPU_CLOCKS_UNHALTED +PMC2 RETIRED_UOPS +PMC3 RETIRED_FLOPS_DOUBLE_ALL + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] PMC1*inverseClock +DP [MFLOP/s] 1.0E-06*(PMC3)/time +CPI PMC1/PMC0 +CPI (based on uops) PMC1/PMC2 +IPC PMC0/PMC1 + +LONG +Formulas: +DP [MFLOP/s] = 1.0E-06*(RETIRED_FLOPS_DOUBLE_ALL)/time +- +Profiling group to measure double precisision FLOP rate. + + diff --git a/collectors/likwid/groups/interlagos/FLOPS_SP.txt b/collectors/likwid/groups/interlagos/FLOPS_SP.txt new file mode 100644 index 0000000..14af2c2 --- /dev/null +++ b/collectors/likwid/groups/interlagos/FLOPS_SP.txt @@ -0,0 +1,23 @@ +SHORT Single Precision MFLOP/s + +EVENTSET +PMC0 RETIRED_INSTRUCTIONS +PMC1 CPU_CLOCKS_UNHALTED +PMC2 RETIRED_UOPS +PMC3 RETIRED_FLOPS_SINGLE_ALL + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] PMC1*inverseClock +SP [MFLOP/s] 1.0E-06*(PMC3)/time +CPI PMC1/PMC0 +CPI (based on uops) PMC1/PMC2 +IPC PMC0/PMC1 + +LONG +Formulas: +SP [MFLOP/s] = 1.0E-06*(RETIRED_FLOPS_SINGLE_ALL)/time +- +Profiling group to measure single precision FLOP rate. + + diff --git a/collectors/likwid/groups/interlagos/FPU_EXCEPTION.txt b/collectors/likwid/groups/interlagos/FPU_EXCEPTION.txt new file mode 100644 index 0000000..0969ae1 --- /dev/null +++ b/collectors/likwid/groups/interlagos/FPU_EXCEPTION.txt @@ -0,0 +1,21 @@ +SHORT Floating point exceptions + +EVENTSET +PMC0 RETIRED_INSTRUCTIONS +PMC1 RETIRED_FP_INSTRUCTIONS_ALL +PMC2 FPU_EXCEPTION_ALL + +METRICS +Runtime (RDTSC) [s] time +Overall FP exception rate PMC2/PMC0 +FP exception rate PMC2/PMC1 + +LONG +Formulas: +Overall FP exception rate = FPU_EXCEPTIONS_ALL / INSTRUCTIONS_RETIRED +FP exception rate = FPU_EXCEPTIONS_ALL / FP_INSTRUCTIONS_RETIRED_ALL +- +Floating point exceptions occur e.g. on the treatment of denormal numbers. +There might be a large penalty if there are too many floating point +exceptions. + diff --git a/collectors/likwid/groups/interlagos/ICACHE.txt b/collectors/likwid/groups/interlagos/ICACHE.txt new file mode 100644 index 0000000..62b91d6 --- /dev/null +++ b/collectors/likwid/groups/interlagos/ICACHE.txt @@ -0,0 +1,23 @@ +SHORT Instruction cache miss rate/ratio + +EVENTSET +PMC0 INSTRUCTION_CACHE_FETCHES +PMC1 INSTRUCTION_CACHE_L2_REFILLS +PMC2 INSTRUCTION_CACHE_SYSTEM_REFILLS +PMC3 RETIRED_INSTRUCTIONS + +METRICS +Runtime (RDTSC) [s] time +L1I request rate PMC0/PMC3 +L1I miss rate (PMC1+PMC2)/PMC3 +L1I miss ratio (PMC1+PMC2)/PMC0 + +LONG +Formulas: +L1I request rate = INSTRUCTION_CACHE_FETCHES / RETIRED_INSTRUCTIONS +L1I miss rate = (INSTRUCTION_CACHE_L2_REFILLS + INSTRUCTION_CACHE_SYSTEM_REFILLS)/RETIRED_INSTRUCTIONS +L1I miss ratio = (INSTRUCTION_CACHE_L2_REFILLS + INSTRUCTION_CACHE_SYSTEM_REFILLS)/INSTRUCTION_CACHE_FETCHES +- +This group measures the locality of your instruction code with regard to the +L1 I-Cache. + diff --git a/collectors/likwid/groups/interlagos/L2.txt b/collectors/likwid/groups/interlagos/L2.txt new file mode 100644 index 0000000..4d90ef8 --- /dev/null +++ b/collectors/likwid/groups/interlagos/L2.txt @@ -0,0 +1,29 @@ +SHORT L2 cache bandwidth in MBytes/s + +EVENTSET +PMC0 DATA_CACHE_REFILLS_ALL +PMC1 DATA_CACHE_REFILLS_SYSTEM +PMC2 CPU_CLOCKS_UNHALTED + +METRICS +Runtime (RDTSC) [s] time +L2 bandwidth [MBytes/s] 1.0E-06*(PMC0-PMC1)*64.0/time +L2 data volume [GBytes] 1.0E-09*(PMC0-PMC1)*64.0 +Cache refill bandwidth System/L2 [MBytes/s] 1.0E-06*PMC0*64.0/time +Cache refill bandwidth System [MBytes/s] 1.0E-06*PMC1*64.0/time + +LONG +Formulas: +L2 bandwidth [MBytes/s] = 1.0E-06*(DATA_CACHE_REFILLS_ALL-DATA_CACHE_REFILLS_SYSTEM)*64/time +L2 data volume [GBytes] = 1.0E-09*(DATA_CACHE_REFILLS_ALL-DATA_CACHE_REFILLS_SYSTEM)*64 +Cache refill bandwidth system/L2 [MBytes/s] = 1.0E-06*DATA_CACHE_REFILLS_ALL*64/time +Cache refill bandwidth system [MBytes/s] = 1.0E-06*DATA_CACHE_REFILLS_SYSTEM*64/time +- +Profiling group to measure L2 cache bandwidth. The bandwidth is +computed by the number of cache line loaded from L2 to L1 and the +number of modified cache lines evicted from the L1. +Note that this bandwidth also included data transfers due to a +write allocate load on a store miss in L1 and copy back transfers if +originated from L2. L2-L2 data volume is the total data volume transferred +between L2 and L1. + diff --git a/collectors/likwid/groups/interlagos/L2CACHE.txt b/collectors/likwid/groups/interlagos/L2CACHE.txt new file mode 100644 index 0000000..49b9555 --- /dev/null +++ b/collectors/likwid/groups/interlagos/L2CACHE.txt @@ -0,0 +1,31 @@ +SHORT L2 cache miss rate/ratio + +EVENTSET +PMC0 RETIRED_INSTRUCTIONS +PMC1 REQUESTS_TO_L2_DC_FILL +PMC2 L2_CACHE_MISS_DC_FILL + +METRICS +Runtime (RDTSC) [s] time +L2 request rate PMC1/PMC0 +L2 miss rate PMC2/PMC0 +L2 miss ratio PMC2/PMC1 + +LONG +Formulas: +L2 request rate = L2_REQUESTS_ALL/INSTRUCTIONS_RETIRED +L2 miss rate = L2_MISSES_ALL/INSTRUCTIONS_RETIRED +L2 miss ratio = L2_MISSES_ALL/L2_REQUESTS_ALL +- +This group measures the locality of your data accesses with regard to the L2 +Cache. L2 request rate tells you how data intensive your code is or how many +data accesses you have on average per instruction. The L2 miss rate gives a +measure how often it was necessary to get cache lines from memory. And finally +L2 miss ratio tells you how many of your memory references required a cache line +to be loaded from a higher level. While the# data cache miss rate might be +given by your algorithm you should try to get data cache miss ratio as low as +possible by increasing your cache reuse. This group is inspired from the +whitepaper -Basic Performance Measurements for AMD Athlon 64, AMD Opteron and +AMD Phenom Processors- from Paul J. Drongowski. + + diff --git a/collectors/likwid/groups/interlagos/L3.txt b/collectors/likwid/groups/interlagos/L3.txt new file mode 100644 index 0000000..5c9ea4d --- /dev/null +++ b/collectors/likwid/groups/interlagos/L3.txt @@ -0,0 +1,29 @@ +SHORT L3 cache bandwidth in MBytes/s + +EVENTSET +PMC0 L2_FILL_WB_FILL +PMC1 L2_FILL_WB_WB +PMC2 CPU_CLOCKS_UNHALTED + +METRICS +Runtime (RDTSC) [s] time +L3 load bandwidth [MBytes/s] 1.0E-06*PMC0*64.0/time +L3 load data volume [GBytes] 1.0E-09*PMC0*64.0 +L3 evict bandwidth [MBytes/s] 1.0E-06*PMC1*64.0/time +L3 evict data volume [GBytes] 1.0E-09*PMC1*64.0 +L3 bandwidth [MBytes/s] 1.0E-06*(PMC0+PMC1)*64.0/time +L3 data volume [GBytes] 1.0E-09*(PMC0+PMC1)*64.0 + +LONG +Formulas: +L3 load bandwidth [MBytes/s] = 1.0E-06*L2_FILL_WB_FILL*64.0/time +L3 load data volume [GBytes] = 1.0E-09*L2_FILL_WB_FILL*64.0 +L3 evict bandwidth [MBytes/s] = 1.0E-06*L2_FILL_WB_WB*64.0/time +L3 evict data volume [GBytes] = 1.0E-09*L2_FILL_WB_WB*64.0 +L3 bandwidth [MBytes/s] = 1.0E-06*(L2_FILL_WB_FILL+L2_FILL_WB_WB)*64/time +L3 data volume [GBytes] = 1.0E-09*(L2_FILL_WB_FILL+L2_FILL_WB_WB)*64 +- +Profiling group to measure L3 cache bandwidth. The bandwidth is +computed by the number of cache line loaded from L3 to L2 and the +number of modified cache lines evicted from the L2. + diff --git a/collectors/likwid/groups/interlagos/L3CACHE.txt b/collectors/likwid/groups/interlagos/L3CACHE.txt new file mode 100644 index 0000000..5a442c6 --- /dev/null +++ b/collectors/likwid/groups/interlagos/L3CACHE.txt @@ -0,0 +1,35 @@ +SHORT L3 cache miss rate/ratio + +EVENTSET +PMC0 RETIRED_INSTRUCTIONS +UPMC0 UNC_READ_REQ_TO_L3_ALL +UPMC1 UNC_L3_CACHE_MISS_ALL +UPMC2 UNC_L3_LATENCY_CYCLE_COUNT +UPMC3 UNC_L3_LATENCY_REQUEST_COUNT + +METRICS +Runtime (RDTSC) [s] time +L3 request rate UPMC0/PMC0 +L3 miss rate UPMC1/PMC0 +L3 miss ratio UPMC1/UPMC0 +L3 average access latency [cycles] UPMC2/UPMC3 + +LONG +Formulas: +L3 request rate = UNC_READ_REQ_TO_L3_ALL/INSTRUCTIONS_RETIRED +L3 miss rate = UNC_L3_CACHE_MISS_ALL/INSTRUCTIONS_RETIRED +L3 miss ratio = UNC_L3_CACHE_MISS_ALL/UNC_READ_REQ_TO_L3_ALL +L3 average access latency = UNC_L3_LATENCY_CYCLE_COUNT/UNC_L3_LATENCY_REQUEST_COUNT +- +This group measures the locality of your data accesses with regard to the L3 +Cache. L3 request rate tells you how data intensive your code is or how many +data accesses you have on average per instruction. The L3 miss rate gives a +measure how often it was necessary to get cache lines from memory. And finally +L3 miss ratio tells you how many of your memory references required a cache line +to be loaded from a higher level. While the# data cache miss rate might be +given by your algorithm you should try to get data cache miss ratio as low as +possible by increasing your cache reuse. This group was inspired from the +whitepaper - Basic Performance Measurements for AMD Athlon 64, AMD Opteron and +AMD Phenom Processors - from Paul J. Drongowski. + + diff --git a/collectors/likwid/groups/interlagos/LINKS.txt b/collectors/likwid/groups/interlagos/LINKS.txt new file mode 100644 index 0000000..dbf3cd0 --- /dev/null +++ b/collectors/likwid/groups/interlagos/LINKS.txt @@ -0,0 +1,26 @@ +SHORT Bandwidth on the Hypertransport links + +EVENTSET +UPMC0 UNC_LINK_TRANSMIT_BW_L0_USE +UPMC1 UNC_LINK_TRANSMIT_BW_L1_USE +UPMC2 UNC_LINK_TRANSMIT_BW_L2_USE +UPMC3 UNC_LINK_TRANSMIT_BW_L3_USE + +METRICS +Runtime (RDTSC) [s] time +Link bandwidth L0 [MBytes/s] 1.0E-06*UPMC0*4.0/time +Link bandwidth L1 [MBytes/s] 1.0E-06*UPMC1*4.0/time +Link bandwidth L2 [MBytes/s] 1.0E-06*UPMC2*4.0/time +Link bandwidth L3 [MBytes/s] 1.0E-06*UPMC3*4.0/time + +LONG +Formulas: +Link bandwidth L0 [MBytes/s] = 1.0E-06*UNC_LINK_TRANSMIT_BW_L0_USE*4.0/time +Link bandwidth L1 [MBytes/s] = 1.0E-06*UNC_LINK_TRANSMIT_BW_L1_USE*4.0/time +Link bandwidth L2 [MBytes/s] = 1.0E-06*UNC_LINK_TRANSMIT_BW_L2_USE*4.0/time +Link bandwidth L3 [MBytes/s] = 1.0E-06*UNC_LINK_TRANSMIT_BW_L3_USE*4.0/time +- +Profiling group to measure the HyperTransport link bandwidth for the four links +of a local node. This indicates the# data flow between different ccNUMA nodes. + + diff --git a/collectors/likwid/groups/interlagos/MEM.txt b/collectors/likwid/groups/interlagos/MEM.txt new file mode 100644 index 0000000..2fa9dfe --- /dev/null +++ b/collectors/likwid/groups/interlagos/MEM.txt @@ -0,0 +1,20 @@ +SHORT Main memory bandwidth in MBytes/s + +EVENTSET +UPMC0 UNC_DRAM_ACCESSES_DCT0_ALL +UPMC1 UNC_DRAM_ACCESSES_DCT1_ALL + +METRICS +Runtime (RDTSC) [s] time +Memory bandwidth [MBytes/s] 1.0E-06*(UPMC0+UPMC1)*64.0/time +Memory data volume [GBytes] 1.0E-09*(UPMC0+UPMC1)*64.0 + +LONG +Formulas: +Memory bandwidth [MBytes/s] = 1.0E-06*(DRAM_ACCESSES_DCTO_ALL+DRAM_ACCESSES_DCT1_ALL)*64/time +Memory data volume [GBytes] = 1.0E-09*(DRAM_ACCESSES_DCTO_ALL+DRAM_ACCESSES_DCT1_ALL)*64 +- +Profiling group to measure memory bandwidth drawn by all cores of a socket. +Note: As this group measures the accesses from all cores it only makes sense +to measure with one core per socket, similar as with the Intel Nehalem Uncore events. + diff --git a/collectors/likwid/groups/interlagos/NUMA.txt b/collectors/likwid/groups/interlagos/NUMA.txt new file mode 100644 index 0000000..79f3618 --- /dev/null +++ b/collectors/likwid/groups/interlagos/NUMA.txt @@ -0,0 +1,28 @@ +SHORT Read/Write Events between the ccNUMA nodes + +EVENTSET +UPMC0 UNC_CPU_TO_DRAM_LOCAL_TO_0 +UPMC1 UNC_CPU_TO_DRAM_LOCAL_TO_1 +UPMC2 UNC_CPU_TO_DRAM_LOCAL_TO_2 +UPMC3 UNC_CPU_TO_DRAM_LOCAL_TO_3 + +METRICS +Runtime (RDTSC) [s] time +DRAM read/write local to 0 [MegaEvents/s] 1.0E-06*UPMC0/time +DRAM read/write local to 1 [MegaEvents/s] 1.0E-06*UPMC1/time +DRAM read/write local to 2 [MegaEvents/s] 1.0E-06*UPMC2/time +DRAM read/write local to 3 [MegaEvents/s] 1.0E-06*UPMC3/time + +LONG +Formulas: +DRAM read/write local to 0 [MegaEvents/s] = 1.0E-06*UNC_CPU_TO_DRAM_LOCAL_TO_0/time +DRAM read/write local to 1 [MegaEvents/s] = 1.0E-06*UNC_CPU_TO_DRAM_LOCAL_TO_1/time +DRAM read/write local to 2 [MegaEvents/s] = 1.0E-06*UNC_CPU_TO_DRAM_LOCAL_TO_2/time +DRAM read/write local to 3 [MegaEvents/s] = 1.0E-06*UNC_CPU_TO_DRAM_LOCAL_TO_3/time +- +Profiling group to measure the traffic from local CPU to the different +DRAM NUMA nodes. This group allows to detect NUMA problems in a threaded +code. You must first determine on which memory domains your code is running. +A code should only have significant traffic to its own memory domain. + + diff --git a/collectors/likwid/groups/interlagos/NUMA_0_3.txt b/collectors/likwid/groups/interlagos/NUMA_0_3.txt new file mode 100644 index 0000000..79f3618 --- /dev/null +++ b/collectors/likwid/groups/interlagos/NUMA_0_3.txt @@ -0,0 +1,28 @@ +SHORT Read/Write Events between the ccNUMA nodes + +EVENTSET +UPMC0 UNC_CPU_TO_DRAM_LOCAL_TO_0 +UPMC1 UNC_CPU_TO_DRAM_LOCAL_TO_1 +UPMC2 UNC_CPU_TO_DRAM_LOCAL_TO_2 +UPMC3 UNC_CPU_TO_DRAM_LOCAL_TO_3 + +METRICS +Runtime (RDTSC) [s] time +DRAM read/write local to 0 [MegaEvents/s] 1.0E-06*UPMC0/time +DRAM read/write local to 1 [MegaEvents/s] 1.0E-06*UPMC1/time +DRAM read/write local to 2 [MegaEvents/s] 1.0E-06*UPMC2/time +DRAM read/write local to 3 [MegaEvents/s] 1.0E-06*UPMC3/time + +LONG +Formulas: +DRAM read/write local to 0 [MegaEvents/s] = 1.0E-06*UNC_CPU_TO_DRAM_LOCAL_TO_0/time +DRAM read/write local to 1 [MegaEvents/s] = 1.0E-06*UNC_CPU_TO_DRAM_LOCAL_TO_1/time +DRAM read/write local to 2 [MegaEvents/s] = 1.0E-06*UNC_CPU_TO_DRAM_LOCAL_TO_2/time +DRAM read/write local to 3 [MegaEvents/s] = 1.0E-06*UNC_CPU_TO_DRAM_LOCAL_TO_3/time +- +Profiling group to measure the traffic from local CPU to the different +DRAM NUMA nodes. This group allows to detect NUMA problems in a threaded +code. You must first determine on which memory domains your code is running. +A code should only have significant traffic to its own memory domain. + + diff --git a/collectors/likwid/groups/interlagos/NUMA_4_7.txt b/collectors/likwid/groups/interlagos/NUMA_4_7.txt new file mode 100644 index 0000000..0e05776 --- /dev/null +++ b/collectors/likwid/groups/interlagos/NUMA_4_7.txt @@ -0,0 +1,28 @@ +SHORT Read/Write Events between the ccNUMA nodes + +EVENTSET +UPMC0 UNC_CPU_TO_DRAM_LOCAL_TO_4 +UPMC1 UNC_CPU_TO_DRAM_LOCAL_TO_5 +UPMC2 UNC_CPU_TO_DRAM_LOCAL_TO_6 +UPMC3 UNC_CPU_TO_DRAM_LOCAL_TO_7 + +METRICS +Runtime (RDTSC) [s] time +DRAM read/write local to 4 [MegaEvents/s] 1.0E-06*UPMC0/time +DRAM read/write local to 5 [MegaEvents/s] 1.0E-06*UPMC1/time +DRAM read/write local to 6 [MegaEvents/s] 1.0E-06*UPMC2/time +DRAM read/write local to 7 [MegaEvents/s] 1.0E-06*UPMC3/time + +LONG +Formulas: +DRAM read/write local to 4 [MegaEvents/s] = 1.0E-06*UNC_CPU_TO_DRAM_LOCAL_TO_0/time +DRAM read/write local to 5 [MegaEvents/s] = 1.0E-06*UNC_CPU_TO_DRAM_LOCAL_TO_1/time +DRAM read/write local to 6 [MegaEvents/s] = 1.0E-06*UNC_CPU_TO_DRAM_LOCAL_TO_2/time +DRAM read/write local to 7 [MegaEvents/s] = 1.0E-06*UNC_CPU_TO_DRAM_LOCAL_TO_3/time +- +Profiling group to measure the traffic from local CPU to the different +DRAM NUMA nodes. This group allows to detect NUMA problems in a threaded +code. You must first determine on which memory domains your code is running. +A code should only have significant traffic to its own memory domain. + + diff --git a/collectors/likwid/groups/ivybridge/BRANCH.txt b/collectors/likwid/groups/ivybridge/BRANCH.txt new file mode 100644 index 0000000..b8d41b2 --- /dev/null +++ b/collectors/likwid/groups/ivybridge/BRANCH.txt @@ -0,0 +1,31 @@ +SHORT Branch prediction miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 BR_INST_RETIRED_ALL_BRANCHES +PMC1 BR_MISP_RETIRED_ALL_BRANCHES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Branch rate PMC0/FIXC0 +Branch misprediction rate PMC1/FIXC0 +Branch misprediction ratio PMC1/PMC0 +Instructions per branch FIXC0/PMC0 + +LONG +Formulas: +Branch rate = BR_INST_RETIRED_ALL_BRANCHES/INSTR_RETIRED_ANY +Branch misprediction rate = BR_MISP_RETIRED_ALL_BRANCHES/INSTR_RETIRED_ANY +Branch misprediction ratio = BR_MISP_RETIRED_ALL_BRANCHES/BR_INST_RETIRED_ALL_BRANCHES +Instructions per branch = INSTR_RETIRED_ANY/BR_INST_RETIRED_ALL_BRANCHES +- +The rates state how often on average a branch or a mispredicted branch occurred +per instruction retired in total. The branch misprediction ratio sets directly +into relation what ratio of all branch instruction where mispredicted. +Instructions per branch is 1/branch rate. + diff --git a/collectors/likwid/groups/ivybridge/CLOCK.txt b/collectors/likwid/groups/ivybridge/CLOCK.txt new file mode 100644 index 0000000..fb19101 --- /dev/null +++ b/collectors/likwid/groups/ivybridge/CLOCK.txt @@ -0,0 +1,26 @@ +SHORT Power and Energy consumption + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PWR0 PWR_PKG_ENERGY +UBOXFIX UNCORE_CLOCK + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +Uncore Clock [MHz] 1.E-06*UBOXFIX/time +CPI FIXC1/FIXC0 +Energy [J] PWR0 +Power [W] PWR0/time + +LONG +Formulas: +Power = PWR_PKG_ENERGY / time +Uncore Clock [MHz] = 1.E-06 * UNCORE_CLOCK / time +- +IvyBridge implements the new RAPL interface. This interface enables to +monitor the consumed energy on the package (socket) level. + diff --git a/collectors/likwid/groups/ivybridge/CYCLE_ACTIVITY.txt b/collectors/likwid/groups/ivybridge/CYCLE_ACTIVITY.txt new file mode 100644 index 0000000..c432a44 --- /dev/null +++ b/collectors/likwid/groups/ivybridge/CYCLE_ACTIVITY.txt @@ -0,0 +1,38 @@ +SHORT Cycle Activities + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 CYCLE_ACTIVITY_CYCLES_L2_PENDING +PMC1 CYCLE_ACTIVITY_CYCLES_LDM_PENDING +PMC2 CYCLE_ACTIVITY_CYCLES_L1D_PENDING +PMC3 CYCLE_ACTIVITY_CYCLES_NO_EXECUTE + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Cycles without execution [%] (PMC3/FIXC1)*100 +Cycles without execution due to L1D [%] (PMC2/FIXC1)*100 +Cycles without execution due to L2 [%] (PMC0/FIXC1)*100 +Cycles without execution due to memory loads [%] (PMC1/FIXC1)*100 + +LONG +Formulas: +Cycles without execution [%] = CYCLE_ACTIVITY_CYCLES_NO_EXECUTE/CPU_CLK_UNHALTED_CORE*100 +Cycles with stalls due to L1D [%] = CYCLE_ACTIVITY_CYCLES_L1D_PENDING/CPU_CLK_UNHALTED_CORE*100 +Cycles with stalls due to L2 [%] = CYCLE_ACTIVITY_CYCLES_L2_PENDING/CPU_CLK_UNHALTED_CORE*100 +Cycles without execution due to memory loads [%] = CYCLE_ACTIVITY_CYCLES_LDM_PENDING/CPU_CLK_UNHALTED_CORE*100 +-- +This performance group measures the cycles while waiting for data from the cache +and memory hierarchy. +CYCLE_ACTIVITY_CYCLES_NO_EXECUTE: Counts number of cycles nothing is executed on +any execution port. +CYCLE_ACTIVITY_CYCLES_L1D_PENDING: Cycles while L1 cache miss demand load is +outstanding. +CYCLE_ACTIVITY_CYCLES_L2_PENDING: Cycles while L2 cache miss demand load is +outstanding. +CYCLE_ACTIVITY_CYCLES_LDM_PENDING: Cycles while memory subsystem has an +outstanding load. diff --git a/collectors/likwid/groups/ivybridge/CYCLE_STALLS.txt b/collectors/likwid/groups/ivybridge/CYCLE_STALLS.txt new file mode 100644 index 0000000..795aeb9 --- /dev/null +++ b/collectors/likwid/groups/ivybridge/CYCLE_STALLS.txt @@ -0,0 +1,45 @@ +SHORT Cycle Activities (Stalls) + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 CYCLE_ACTIVITY_STALLS_L2_PENDING +PMC1 CYCLE_ACTIVITY_STALLS_LDM_PENDING +PMC2 CYCLE_ACTIVITY_STALLS_L1D_PENDING +PMC3 CYCLE_ACTIVITY_STALLS_TOTAL + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Total execution stalls PMC3 +Stalls caused by L1D misses [%] (PMC2/PMC3)*100 +Stalls caused by L2 misses [%] (PMC0/PMC3)*100 +Stalls caused by memory loads [%] (PMC1/PMC3)*100 +Execution stall rate [%] (PMC3/FIXC1)*100 +Stalls caused by L1D misses rate [%] (PMC2/FIXC1)*100 +Stalls caused by L2 misses rate [%] (PMC0/FIXC1)*100 +Stalls caused by memory loads rate [%] (PMC1/FIXC1)*100 + +LONG +Formulas: +Total execution stalls = CYCLE_ACTIVITY_STALLS_TOTAL +Stalls caused by L1D misses [%] = (CYCLE_ACTIVITY_STALLS_L1D_PENDING/CYCLE_ACTIVITY_STALLS_TOTAL)*100 +Stalls caused by L2 misses [%] = (CYCLE_ACTIVITY_STALLS_L2_PENDING/CYCLE_ACTIVITY_STALLS_TOTAL)*100 +Stalls caused by memory loads [%] = (CYCLE_ACTIVITY_STALLS_LDM_PENDING/CYCLE_ACTIVITY_STALLS_TOTAL)*100 +Execution stall rate [%] = (CYCLE_ACTIVITY_STALLS_TOTAL/CPU_CLK_UNHALTED_CORE)*100 +Stalls caused by L1D misses rate [%] = (CYCLE_ACTIVITY_STALLS_L1D_PENDING/CPU_CLK_UNHALTED_CORE)*100 +Stalls caused by L2 misses rate [%] = (CYCLE_ACTIVITY_STALLS_L2_PENDING/CPU_CLK_UNHALTED_CORE)*100 +Stalls caused by memory loads rate [%] = (CYCLE_ACTIVITY_STALLS_LDM_PENDING/CPU_CLK_UNHALTED_CORE)*100 +-- +This performance group measures the stalls caused by data traffic in the cache +hierarchy. +CYCLE_ACTIVITY_STALLS_TOTAL: Total execution stalls. +CYCLE_ACTIVITY_STALLS_L1D_PENDING: Execution stalls while L1 cache miss demand +load is outstanding. +CYCLE_ACTIVITY_STALLS_L2_PENDING: Execution stalls while L2 cache miss demand +load is outstanding. +CYCLE_ACTIVITY_STALLS_LDM_PENDING: Execution stalls while memory subsystem has +an outstanding load. diff --git a/collectors/likwid/groups/ivybridge/DATA.txt b/collectors/likwid/groups/ivybridge/DATA.txt new file mode 100644 index 0000000..967cbad --- /dev/null +++ b/collectors/likwid/groups/ivybridge/DATA.txt @@ -0,0 +1,22 @@ +SHORT Load to store ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 MEM_UOPS_RETIRED_LOADS +PMC1 MEM_UOPS_RETIRED_STORES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Load to store ratio PMC0/PMC1 + +LONG +Formulas: +Load to store ratio = MEM_UOPS_RETIRED_LOADS/MEM_UOPS_RETIRED_STORES +- +This is a metric to determine your load to store ratio. + diff --git a/collectors/likwid/groups/ivybridge/DIVIDE.txt b/collectors/likwid/groups/ivybridge/DIVIDE.txt new file mode 100644 index 0000000..f8cb0b3 --- /dev/null +++ b/collectors/likwid/groups/ivybridge/DIVIDE.txt @@ -0,0 +1,24 @@ +SHORT Divide unit information + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 ARITH_NUM_DIV +PMC1 ARITH_FPU_DIV_ACTIVE + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Number of divide ops PMC0 +Avg. divide unit usage duration PMC1/PMC0 + +LONG +Formulas: +Number of divide ops = ARITH_NUM_DIV +Avg. divide unit usage duration = ARITH_FPU_DIV_ACTIVE/ARITH_NUM_DIV +- +This performance group measures the average latency of divide operations diff --git a/collectors/likwid/groups/ivybridge/ENERGY.txt b/collectors/likwid/groups/ivybridge/ENERGY.txt new file mode 100644 index 0000000..92a6915 --- /dev/null +++ b/collectors/likwid/groups/ivybridge/ENERGY.txt @@ -0,0 +1,37 @@ +SHORT Power and Energy consumption + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +TMP0 TEMP_CORE +PWR0 PWR_PKG_ENERGY +PWR1 PWR_PP0_ENERGY +PWR2 PWR_PP1_ENERGY +PWR3 PWR_DRAM_ENERGY + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Temperature [C] TMP0 +Energy [J] PWR0 +Power [W] PWR0/time +Energy PP0 [J] PWR1 +Power PP0 [W] PWR1/time +Energy PP1 [J] PWR2 +Power PP1 [W] PWR2/time +Energy DRAM [J] PWR3 +Power DRAM [W] PWR3/time + +LONG +Formulas: +Power = PWR_PKG_ENERGY / time +Power PP0 = PWR_PP0_ENERGY / time +Power PP1 = PWR_PP1_ENERGY / time +Power DRAM = PWR_DRAM_ENERGY / time +- +IvyBridge implements the new RAPL interface. This interface enables to +monitor the consumed energy on the package (socket), the PP0 domain +and DRAM level. The PP0 domain often refers to only the CPU cores. diff --git a/collectors/likwid/groups/ivybridge/FALSE_SHARE.txt b/collectors/likwid/groups/ivybridge/FALSE_SHARE.txt new file mode 100644 index 0000000..fbec3f4 --- /dev/null +++ b/collectors/likwid/groups/ivybridge/FALSE_SHARE.txt @@ -0,0 +1,25 @@ +SHORT False sharing + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 MEM_LOAD_UOPS_LLC_HIT_RETIRED_XSNP_HITM +PMC2 MEM_LOAD_UOPS_RETIRED_ALL + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Local LLC false sharing [MByte] 1.E-06*PMC0*64 +Local LLC false sharing rate PMC0/PMC2 + +LONG +Formulas: +Local LLC false sharing [MByte] = 1.E-06*MEM_LOAD_UOPS_LLC_HIT_RETIRED_XSNP_HITM*64 +Local LLC false sharing rate = MEM_LOAD_UOPS_LLC_HIT_RETIRED_XSNP_HITM/MEM_LOAD_UOPS_RETIRED_ALL +- +False-sharing of cache lines can dramatically reduce the performance of an +application. This performance group measures the L3 traffic induced by false-sharing. +The false-sharing rate uses all memory loads as reference. diff --git a/collectors/likwid/groups/ivybridge/FLOPS_AVX.txt b/collectors/likwid/groups/ivybridge/FLOPS_AVX.txt new file mode 100644 index 0000000..526d550 --- /dev/null +++ b/collectors/likwid/groups/ivybridge/FLOPS_AVX.txt @@ -0,0 +1,25 @@ +SHORT Packed AVX MFLOP/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 SIMD_FP_256_PACKED_SINGLE +PMC1 SIMD_FP_256_PACKED_DOUBLE + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Packed SP [MFLOP/s] 1.0E-06*(PMC0*8.0)/time +Packed DP [MFLOP/s] 1.0E-06*(PMC1*4.0)/time + +LONG +Formulas: +Packed SP [MFLOP/s] = 1.0E-06*(SIMD_FP_256_PACKED_SINGLE*8)/runtime +Packed DP [MFLOP/s] = 1.0E-06*(SIMD_FP_256_PACKED_DOUBLE*4)/runtime +- +Packed 32b AVX FLOPs rates. Please note that the current FLOP measurements on IvyBridge are +potentially wrong. So you cannot trust these counters at the moment! + diff --git a/collectors/likwid/groups/ivybridge/FLOPS_DP.txt b/collectors/likwid/groups/ivybridge/FLOPS_DP.txt new file mode 100644 index 0000000..e737098 --- /dev/null +++ b/collectors/likwid/groups/ivybridge/FLOPS_DP.txt @@ -0,0 +1,33 @@ +SHORT Double Precision MFLOP/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 FP_COMP_OPS_EXE_SSE_FP_PACKED_DOUBLE +PMC1 FP_COMP_OPS_EXE_SSE_FP_SCALAR_DOUBLE +PMC2 SIMD_FP_256_PACKED_DOUBLE + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +DP [MFLOP/s] 1.0E-06*(PMC0*2.0+PMC1+PMC2*4.0)/time +AVX DP [MFLOP/s] 1.0E-06*(PMC2*4.0)/time +Packed [MUOPS/s] 1.0E-06*(PMC0+PMC2)/time +Scalar [MUOPS/s] 1.0E-06*PMC1/time +Vectorization ratio 100*(PMC0+PMC2)/(PMC0+PMC1+PMC2) + +LONG +Formulas: +DP [MFLOP/s] = 1.0E-06*(FP_COMP_OPS_EXE_SSE_FP_PACKED*2+FP_COMP_OPS_EXE_SSE_FP_SCALAR+SIMD_FP_256_PACKED_DOUBLE*4)/runtime +AVX DP [MFLOP/s] = 1.0E-06*(SIMD_FP_256_PACKED_DOUBLE*4)/runtime +Packed [MUOPS/s] = 1.0E-06*(FP_COMP_OPS_EXE_SSE_FP_PACKED_DOUBLE+SIMD_FP_256_PACKED_DOUBLE)/runtime +Scalar [MUOPS/s] = 1.0E-06*FP_COMP_OPS_EXE_SSE_FP_SCALAR_DOUBLE/runtime +Vectorization ratio = 100*(FP_COMP_OPS_EXE_SSE_FP_PACKED_DOUBLE+SIMD_FP_256_PACKED_DOUBLE)/(FP_COMP_OPS_EXE_SSE_FP_SCALAR_DOUBLE+FP_COMP_OPS_EXE_SSE_FP_PACKED_DOUBLE+SIMD_FP_256_PACKED_DOUBLE) +- +SSE scalar and packed double precision FLOP rates. Please note that the current +FLOP measurements on IvyBridge are potentially wrong. +So you cannot trust these counters at the moment! + diff --git a/collectors/likwid/groups/ivybridge/FLOPS_SP.txt b/collectors/likwid/groups/ivybridge/FLOPS_SP.txt new file mode 100644 index 0000000..7483722 --- /dev/null +++ b/collectors/likwid/groups/ivybridge/FLOPS_SP.txt @@ -0,0 +1,33 @@ +SHORT Single Precision MFLOP/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 FP_COMP_OPS_EXE_SSE_FP_PACKED_SINGLE +PMC1 FP_COMP_OPS_EXE_SSE_FP_SCALAR_SINGLE +PMC2 SIMD_FP_256_PACKED_SINGLE + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +SP [MFLOP/s] 1.0E-06*(PMC0*4.0+PMC1+PMC2*8.0)/time +AVX SP [MFLOP/s] 1.0E-06*(PMC2*8.0)/time +Packed [MUOPS/s] 1.0E-06*(PMC0+PMC2)/time +Scalar [MUOPS/s] 1.0E-06*PMC1/time +Vectorization ratio 100*(PMC0+PMC2)/(PMC0+PMC1+PMC2) + +LONG +Formulas: +SP [MFLOP/s] = 1.0E-06*(FP_COMP_OPS_EXE_SSE_FP_PACKED*4+FP_COMP_OPS_EXE_SSE_FP_SCALAR+SIMD_FP_256_PACKED_SINGLE*8)/runtime +AVX SP [MFLOP/s] = 1.0E-06*(SIMD_FP_256_PACKED_SINGLE*8)/runtime +Packed [MUOPS/s] = 1.0E-06*(FP_COMP_OPS_EXE_SSE_FP_PACKED_SINGLE+SIMD_FP_256_PACKED_SINGLE)/runtime +Scalar [MUOPS/s] = 1.0E-06*FP_COMP_OPS_EXE_SSE_FP_SCALAR_SINGLE/runtime +Vectorization ratio = 100*(FP_COMP_OPS_EXE_SSE_FP_PACKED_SINGLE+SIMD_FP_256_PACKED_SINGLE)/(FP_COMP_OPS_EXE_SSE_FP_SCALAR_SINGLE+FP_COMP_OPS_EXE_SSE_FP_PACKED_SINGLE+SIMD_FP_256_PACKED_SINGLE) +- +SSE scalar and packed single precision FLOP rates. Please note that the current +FLOP measurements on IvyBridge are potentially wrong. +So you cannot trust these counters at the moment! + diff --git a/collectors/likwid/groups/ivybridge/ICACHE.txt b/collectors/likwid/groups/ivybridge/ICACHE.txt new file mode 100644 index 0000000..f1e2335 --- /dev/null +++ b/collectors/likwid/groups/ivybridge/ICACHE.txt @@ -0,0 +1,33 @@ +SHORT Instruction cache miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 ICACHE_ACCESSES +PMC1 ICACHE_MISSES +PMC2 ICACHE_IFETCH_STALL +PMC3 ILD_STALL_IQ_FULL + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L1I request rate PMC0/FIXC0 +L1I miss rate PMC1/FIXC0 +L1I miss ratio PMC1/PMC0 +L1I stalls PMC2 +L1I stall rate PMC2/FIXC0 +L1I queue full stalls PMC3 +L1I queue full stall rate PMC3/FIXC0 + +LONG +Formulas: +L1I request rate = ICACHE_ACCESSES / INSTR_RETIRED_ANY +L1I miss rate = ICACHE_MISSES / INSTR_RETIRED_ANY +L1I miss ratio = ICACHE_MISSES / ICACHE_ACCESSES +L1I stalls = ICACHE_IFETCH_STALL +L1I stall rate = ICACHE_IFETCH_STALL / INSTR_RETIRED_ANY +- +This group measures some L1 instruction cache metrics. diff --git a/collectors/likwid/groups/ivybridge/L2.txt b/collectors/likwid/groups/ivybridge/L2.txt new file mode 100644 index 0000000..376e974 --- /dev/null +++ b/collectors/likwid/groups/ivybridge/L2.txt @@ -0,0 +1,38 @@ +SHORT L2 cache bandwidth in MBytes/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 L1D_REPLACEMENT +PMC1 L1D_M_EVICT +PMC2 ICACHE_MISSES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L2D load bandwidth [MBytes/s] 1.0E-06*PMC0*64.0/time +L2D load data volume [GBytes] 1.0E-09*PMC0*64.0 +L2D evict bandwidth [MBytes/s] 1.0E-06*PMC1*64.0/time +L2D evict data volume [GBytes] 1.0E-09*PMC1*64.0 +L2 bandwidth [MBytes/s] 1.0E-06*(PMC0+PMC1+PMC2)*64.0/time +L2 data volume [GBytes] 1.0E-09*(PMC0+PMC1+PMC2)*64.0 + +LONG +Formulas: +L2D load bandwidth [MBytes/s] = 1.0E-06*L1D_REPLACEMENT*64.0/time +L2D load data volume [GBytes] = 1.0E-09*L1D_REPLACEMENT*64.0 +L2D evict bandwidth [MBytes/s] = 1.0E-06*L1D_M_EVICT*64.0/time +L2D evict data volume [GBytes] = 1.0E-09*L1D_M_EVICT*64.0 +L2 bandwidth [MBytes/s] = 1.0E-06*(L1D_REPLACEMENT+L1D_M_EVICT+ICACHE_MISSES)*64/time +L2 data volume [GBytes] = 1.0E-09*(L1D_REPLACEMENT+L1D_M_EVICT+ICACHE_MISSES)*64 +- +Profiling group to measure L2 cache bandwidth. The bandwidth is computed by the +number of cache line allocated in the L1 and the number of modified cache lines +evicted from the L1. The group also outputs total data volume transferred between +L2 and L1. Note that this bandwidth also includes data transfers due to a write +allocate load on a store miss in L1 and cache lines transferred it the instruction +cache. + diff --git a/collectors/likwid/groups/ivybridge/L2CACHE.txt b/collectors/likwid/groups/ivybridge/L2CACHE.txt new file mode 100644 index 0000000..9b5dd4b --- /dev/null +++ b/collectors/likwid/groups/ivybridge/L2CACHE.txt @@ -0,0 +1,34 @@ +SHORT L2 cache miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 L2_TRANS_ALL_REQUESTS +PMC1 L2_RQSTS_MISS + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L2 request rate PMC0/FIXC0 +L2 miss rate PMC1/FIXC0 +L2 miss ratio PMC1/PMC0 + +LONG +Formulas: +L2 request rate = L2_TRANS_ALL_REQUESTS/INSTR_RETIRED_ANY +L2 miss rate = L2_RQSTS_MISS/INSTR_RETIRED_ANY +L2 miss ratio = L2_RQSTS_MISS/L2_TRANS_ALL_REQUESTS +- +This group measures the locality of your data accesses with regard to the +L2 cache. L2 request rate tells you how data intensive your code is +or how many data accesses you have on average per instruction. +The L2 miss rate gives a measure how often it was necessary to get +cache lines from memory. And finally L2 miss ratio tells you how many of your +memory references required a cache line to be loaded from a higher level. +While the# data cache miss rate might be given by your algorithm you should +try to get data cache miss ratio as low as possible by increasing your cache reuse. + + diff --git a/collectors/likwid/groups/ivybridge/L3.txt b/collectors/likwid/groups/ivybridge/L3.txt new file mode 100644 index 0000000..f0a8aad --- /dev/null +++ b/collectors/likwid/groups/ivybridge/L3.txt @@ -0,0 +1,36 @@ +SHORT L3 cache bandwidth in MBytes/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 L2_LINES_IN_ALL +PMC1 L2_LINES_OUT_DIRTY_ALL + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L3 load bandwidth [MBytes/s] 1.0E-06*PMC0*64.0/time +L3 load data volume [GBytes] 1.0E-09*PMC0*64.0 +L3 evict bandwidth [MBytes/s] 1.0E-06*PMC1*64.0/time +L3 evict data volume [GBytes] 1.0E-09*PMC1*64.0 +L3 bandwidth [MBytes/s] 1.0E-06*(PMC0+PMC1)*64.0/time +L3 data volume [GBytes] 1.0E-09*(PMC0+PMC1)*64.0 + +LONG +Formulas: +L3 load bandwidth [MBytes/s] = 1.0E-06*L2_LINES_IN_ALL*64.0/time +L3 load data volume [GBytes] = 1.0E-09*L2_LINES_IN_ALL*64.0 +L3 evict bandwidth [MBytes/s] = 1.0E-06*L2_LINES_OUT_DIRTY_ALL*64.0/time +L3 evict data volume [GBytes] = 1.0E-09*L2_LINES_OUT_DIRTY_ALL*64.0 +L3 bandwidth [MBytes/s] = 1.0E-06*(L2_LINES_IN_ALL+L2_LINES_OUT_DIRTY_ALL)*64/time +L3 data volume [GBytes] = 1.0E-09*(L2_LINES_IN_ALL+L2_LINES_OUT_DIRTY_ALL)*64 +- +Profiling group to measure L3 cache bandwidth. The bandwidth is computed by the +number of cache line allocated in the L2 and the number of modified cache lines +evicted from the L2. This group also output data volume transferred between the +L3 and measured cores L2 caches. Note that this bandwidth also includes data +transfers due to a write allocate load on a store miss in L2. + diff --git a/collectors/likwid/groups/ivybridge/L3CACHE.txt b/collectors/likwid/groups/ivybridge/L3CACHE.txt new file mode 100644 index 0000000..9f3036f --- /dev/null +++ b/collectors/likwid/groups/ivybridge/L3CACHE.txt @@ -0,0 +1,36 @@ +SHORT L3 cache miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 MEM_LOAD_UOPS_RETIRED_L3_ALL +PMC1 MEM_LOAD_UOPS_RETIRED_L3_MISS +PMC2 UOPS_RETIRED_ALL + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L3 request rate (PMC0)/PMC2 +L3 miss rate PMC1/PMC2 +L3 miss ratio PMC1/PMC0 + +LONG +Formulas: +L3 request rate = MEM_LOAD_UOPS_RETIRED_L3_ALL/UOPS_RETIRED_ALL +L3 miss rate = MEM_LOAD_UOPS_RETIRED_L3_MISS/UOPS_RETIRED_ALL +L3 miss ratio = MEM_LOAD_UOPS_RETIRED_L3_MISS/MEM_LOAD_UOPS_RETIRED_L3_ALL +- +This group measures the locality of your data accesses with regard to the +L3 cache. L3 request rate tells you how data intensive your code is +or how many data accesses you have on average per instruction. +The L3 miss rate gives a measure how often it was necessary to get +cache lines from memory. And finally L3 miss ratio tells you how many of your +memory references required a cache line to be loaded from a higher level. +While the# data cache miss rate might be given by your algorithm you should +try to get data cache miss ratio as low as possible by increasing your cache reuse. + + diff --git a/collectors/likwid/groups/ivybridge/PORT_USAGE.txt b/collectors/likwid/groups/ivybridge/PORT_USAGE.txt new file mode 100644 index 0000000..d509607 --- /dev/null +++ b/collectors/likwid/groups/ivybridge/PORT_USAGE.txt @@ -0,0 +1,40 @@ +SHORT Execution port utilization + +REQUIRE_NOHT + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 UOPS_DISPATCHED_PORT_PORT_0 +PMC1 UOPS_DISPATCHED_PORT_PORT_1 +PMC2 UOPS_DISPATCHED_PORT_PORT_2 +PMC3 UOPS_DISPATCHED_PORT_PORT_3 +PMC4 UOPS_DISPATCHED_PORT_PORT_4 +PMC5 UOPS_DISPATCHED_PORT_PORT_5 + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Port0 usage ratio PMC0/(PMC0+PMC1+PMC2+PMC3+PMC4+PMC5) +Port1 usage ratio PMC1/(PMC0+PMC1+PMC2+PMC3+PMC4+PMC5) +Port2 usage ratio PMC2/(PMC0+PMC1+PMC2+PMC3+PMC4+PMC5) +Port3 usage ratio PMC3/(PMC0+PMC1+PMC2+PMC3+PMC4+PMC5) +Port4 usage ratio PMC4/(PMC0+PMC1+PMC2+PMC3+PMC4+PMC5) +Port5 usage ratio PMC5/(PMC0+PMC1+PMC2+PMC3+PMC4+PMC5) + +LONG +Formulas: +Port0 usage ratio = UOPS_DISPATCHED_PORT_PORT_0/SUM(UOPS_DISPATCHED_PORT_PORT_*) +Port1 usage ratio = UOPS_DISPATCHED_PORT_PORT_1/SUM(UOPS_DISPATCHED_PORT_PORT_*) +Port2 usage ratio = UOPS_DISPATCHED_PORT_PORT_2/SUM(UOPS_DISPATCHED_PORT_PORT_*) +Port3 usage ratio = UOPS_DISPATCHED_PORT_PORT_3/SUM(UOPS_DISPATCHED_PORT_PORT_*) +Port4 usage ratio = UOPS_DISPATCHED_PORT_PORT_4/SUM(UOPS_DISPATCHED_PORT_PORT_*) +Port5 usage ratio = UOPS_DISPATCHED_PORT_PORT_5/SUM(UOPS_DISPATCHED_PORT_PORT_*) +- +This group measures the execution port utilization in a CPU core. The group can +only be measured when HyperThreading is disabled because only then each CPU core +can program eight counters. diff --git a/collectors/likwid/groups/ivybridge/RECOVERY.txt b/collectors/likwid/groups/ivybridge/RECOVERY.txt new file mode 100644 index 0000000..7928ee4 --- /dev/null +++ b/collectors/likwid/groups/ivybridge/RECOVERY.txt @@ -0,0 +1,22 @@ +SHORT Recovery duration + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 INT_MISC_RECOVERY_CYCLES +PMC1 INT_MISC_RECOVERY_COUNT + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Avg. recovery duration PMC0/PMC1 + +LONG +Formulas: +Avg. recovery duration = INT_MISC_RECOVERY_CYCLES/INT_MISC_RECOVERY_COUNT +- +This group measures the duration of recoveries after SSE exception, memory +disambiguation, etc... diff --git a/collectors/likwid/groups/ivybridge/TLB_DATA.txt b/collectors/likwid/groups/ivybridge/TLB_DATA.txt new file mode 100644 index 0000000..8d94e05 --- /dev/null +++ b/collectors/likwid/groups/ivybridge/TLB_DATA.txt @@ -0,0 +1,35 @@ +SHORT L2 data TLB miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 DTLB_LOAD_MISSES_CAUSES_A_WALK +PMC1 DTLB_STORE_MISSES_CAUSES_A_WALK +PMC2 DTLB_LOAD_MISSES_WALK_DURATION +PMC3 DTLB_STORE_MISSES_WALK_DURATION + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L1 DTLB load misses PMC0 +L1 DTLB load miss rate PMC0/FIXC0 +L1 DTLB load miss duration [Cyc] PMC2/PMC0 +L1 DTLB store misses PMC1 +L1 DTLB store miss rate PMC1/FIXC0 +L1 DTLB store miss duration [Cyc] PMC3/PMC1 + +LONG +Formulas: +L1 DTLB load misses = DTLB_LOAD_MISSES_CAUSES_A_WALK +L1 DTLB load miss rate = DTLB_LOAD_MISSES_CAUSES_A_WALK / INSTR_RETIRED_ANY +L1 DTLB load miss duration [Cyc] = DTLB_LOAD_MISSES_WALK_DURATION / DTLB_LOAD_MISSES_CAUSES_A_WALK +L1 DTLB store misses = DTLB_STORE_MISSES_CAUSES_A_WALK +L1 DTLB store miss rate = DTLB_STORE_MISSES_CAUSES_A_WALK / INSTR_RETIRED_ANY +L1 DTLB store miss duration [Cyc] = DTLB_STORE_MISSES_WALK_DURATION / DTLB_STORE_MISSES_CAUSES_A_WALK +- +The DTLB load and store miss rates gives a measure how often a TLB miss occurred +per instruction. The duration measures the time in cycles how long a walk did take. + diff --git a/collectors/likwid/groups/ivybridge/TLB_INSTR.txt b/collectors/likwid/groups/ivybridge/TLB_INSTR.txt new file mode 100644 index 0000000..235d977 --- /dev/null +++ b/collectors/likwid/groups/ivybridge/TLB_INSTR.txt @@ -0,0 +1,28 @@ +SHORT L1 Instruction TLB miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 ITLB_MISSES_CAUSES_A_WALK +PMC1 ITLB_MISSES_WALK_DURATION + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L1 ITLB misses PMC0 +L1 ITLB miss rate PMC0/FIXC0 +L1 ITLB miss duration [Cyc] PMC1/PMC0 + + +LONG +Formulas: +L1 ITLB misses = ITLB_MISSES_CAUSES_A_WALK +L1 ITLB miss rate = ITLB_MISSES_CAUSES_A_WALK / INSTR_RETIRED_ANY +L1 ITLB miss duration [Cyc] = ITLB_MISSES_WALK_DURATION / ITLB_MISSES_CAUSES_A_WALK +- +The ITLB miss rates gives a measure how often a TLB miss occurred +per instruction. The duration measures the time in cycles how long a walk did take. + diff --git a/collectors/likwid/groups/ivybridge/TMA.txt b/collectors/likwid/groups/ivybridge/TMA.txt new file mode 100644 index 0000000..afb4126 --- /dev/null +++ b/collectors/likwid/groups/ivybridge/TMA.txt @@ -0,0 +1,48 @@ +SHORT Top down cycle allocation + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 UOPS_ISSUED_ANY +PMC1 UOPS_RETIRED_RETIRE_SLOTS +PMC2 IDQ_UOPS_NOT_DELIVERED_CORE +PMC3 INT_MISC_RECOVERY_CYCLES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +IPC FIXC0/FIXC1 +Total Slots 4*FIXC1 +Slots Retired PMC1 +Fetch Bubbles PMC2 +Recovery Bubbles 4*PMC3 +Front End [%] PMC2/(4*FIXC1)*100 +Speculation [%] (PMC0-PMC1+(4*PMC3))/(4*FIXC1)*100 +Retiring [%] PMC1/(4*FIXC1)*100 +Back End [%] (1-((PMC2+PMC0+(4*PMC3))/(4*FIXC1)))*100 + +LONG +Formulas: +Total Slots = 4*CPU_CLK_UNHALTED_CORE +Slots Retired = UOPS_RETIRED_RETIRE_SLOTS +Fetch Bubbles = IDQ_UOPS_NOT_DELIVERED_CORE +Recovery Bubbles = 4*INT_MISC_RECOVERY_CYCLES +Front End [%] = IDQ_UOPS_NOT_DELIVERED_CORE/(4*CPU_CLK_UNHALTED_CORE)*100 +Speculation [%] = (UOPS_ISSUED_ANY-UOPS_RETIRED_RETIRE_SLOTS+(4*INT_MISC_RECOVERY_CYCLES))/(4*CPU_CLK_UNHALTED_CORE)*100 +Retiring [%] = UOPS_RETIRED_RETIRE_SLOTS/(4*CPU_CLK_UNHALTED_CORE)*100 +Back End [%] = (1-((IDQ_UOPS_NOT_DELIVERED_CORE+UOPS_ISSUED_ANY+(4*INT_MISC_RECOVERY_CYCLES))/(4*CPU_CLK_UNHALTED_CORE)))*100 +-- +This performance group measures cycles to determine percentage of time spent in +front end, back end, retiring and speculation. These metrics are published and +verified by Intel. Further information: +Webpage describing Top-Down Method and its usage in Intel vTune: +https://software.intel.com/en-us/vtune-amplifier-help-tuning-applications-using-a-top-down-microarchitecture-analysis-method +Paper by Yasin Ahmad: +https://sites.google.com/site/analysismethods/yasin-pubs/TopDown-Yasin-ISPASS14.pdf?attredirects=0 +Slides by Yasin Ahmad: +http://www.cs.technion.ac.il/~erangi/TMA_using_Linux_perf__Ahmad_Yasin.pdf +The performance group was originally published here: +http://perf.mvermeulen.com/2018/04/14/top-down-performance-counter-analysis-part-1-likwid/ diff --git a/collectors/likwid/groups/ivybridge/UOPS.txt b/collectors/likwid/groups/ivybridge/UOPS.txt new file mode 100644 index 0000000..e6cc208 --- /dev/null +++ b/collectors/likwid/groups/ivybridge/UOPS.txt @@ -0,0 +1,35 @@ +SHORT UOPs execution info + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 UOPS_ISSUED_ANY +PMC1 UOPS_EXECUTED_THREAD +PMC2 UOPS_RETIRED_ALL +PMC3 UOPS_ISSUED_FLAGS_MERGE + + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Issued UOPs PMC0 +Merged UOPs PMC3 +Executed UOPs PMC1 +Retired UOPs PMC2 + +LONG +Formulas: +Issued UOPs = UOPS_ISSUED_ANY +Merged UOPs = UOPS_ISSUED_FLAGS_MERGE +Executed UOPs = UOPS_EXECUTED_THREAD +Retired UOPs = UOPS_RETIRED_ALL +- +This group returns information about the instruction pipeline. It measures the +issued, executed and retired uOPs and returns the number of uOPs which were issued +but not executed as well as the number of uOPs which were executed but never retired. +The executed but not retired uOPs commonly come from speculatively executed branches. + diff --git a/collectors/likwid/groups/ivybridge/UOPS_EXEC.txt b/collectors/likwid/groups/ivybridge/UOPS_EXEC.txt new file mode 100644 index 0000000..7042df7 --- /dev/null +++ b/collectors/likwid/groups/ivybridge/UOPS_EXEC.txt @@ -0,0 +1,31 @@ +SHORT UOPs execution + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 UOPS_EXECUTED_USED_CYCLES +PMC1 UOPS_EXECUTED_STALL_CYCLES +PMC2 CPU_CLOCK_UNHALTED_TOTAL_CYCLES +PMC3:EDGEDETECT UOPS_EXECUTED_STALL_CYCLES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Used cycles ratio [%] 100*PMC0/PMC2 +Unused cycles ratio [%] 100*PMC1/PMC2 +Avg stall duration [cycles] PMC1/PMC3:EDGEDETECT + + +LONG +Formulas: +Used cycles ratio [%] = 100*UOPS_EXECUTED_USED_CYCLES/CPU_CLK_UNHALTED_CORE +Unused cycles ratio [%] = 100*UOPS_EXECUTED_STALL_CYCLES/CPU_CLK_UNHALTED_CORE +Avg stall duration [cycles] = UOPS_EXECUTED_STALL_CYCLES/UOPS_EXECUTED_STALL_CYCLES:EDGEDETECT +- +This performance group returns the ratios of used and unused cycles regarding +the execution stage in the pipeline. Used cycles are all cycles where uOPs are +executed while unused cycles refer to pipeline stalls. Moreover, the group +calculates the average stall duration in cycles. diff --git a/collectors/likwid/groups/ivybridge/UOPS_ISSUE.txt b/collectors/likwid/groups/ivybridge/UOPS_ISSUE.txt new file mode 100644 index 0000000..9aac923 --- /dev/null +++ b/collectors/likwid/groups/ivybridge/UOPS_ISSUE.txt @@ -0,0 +1,31 @@ +SHORT UOPs issueing + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 UOPS_ISSUED_USED_CYCLES +PMC1 UOPS_ISSUED_STALL_CYCLES +PMC2 CPU_CLOCK_UNHALTED_TOTAL_CYCLES +PMC3:EDGEDETECT UOPS_ISSUED_STALL_CYCLES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Used cycles ratio [%] 100*PMC0/PMC2 +Unused cycles ratio [%] 100*PMC1/PMC2 +Avg stall duration [cycles] PMC1/PMC3:EDGEDETECT + + +LONG +Formulas: +Used cycles ratio [%] = 100*UOPS_ISSUED_USED_CYCLES/CPU_CLK_UNHALTED_CORE +Unused cycles ratio [%] = 100*UOPS_ISSUED_STALL_CYCLES/CPU_CLK_UNHALTED_CORE +Avg stall duration [cycles] = UOPS_ISSUED_STALL_CYCLES/UOPS_ISSUED_STALL_CYCLES:EDGEDETECT +- +This performance group returns the ratios of used and unused cycles regarding +the issue stage in the pipeline. Used cycles are all cycles where uOPs are +issued while unused cycles refer to pipeline stalls. Moreover, the group +calculates the average stall duration in cycles. diff --git a/collectors/likwid/groups/ivybridge/UOPS_RETIRE.txt b/collectors/likwid/groups/ivybridge/UOPS_RETIRE.txt new file mode 100644 index 0000000..0f37585 --- /dev/null +++ b/collectors/likwid/groups/ivybridge/UOPS_RETIRE.txt @@ -0,0 +1,31 @@ +SHORT UOPs retirement + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 UOPS_RETIRED_USED_CYCLES +PMC1 UOPS_RETIRED_STALL_CYCLES +PMC2 CPU_CLOCK_UNHALTED_TOTAL_CYCLES +PMC3:EDGEDETECT UOPS_RETIRED_STALL_CYCLES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Used cycles ratio [%] 100*PMC0/PMC2 +Unused cycles ratio [%] 100*PMC1/PMC2 +Avg stall duration [cycles] PMC1/PMC3:EDGEDETECT + + +LONG +Formulas: +Used cycles ratio [%] = 100*UOPS_RETIRED_USED_CYCLES/CPU_CLK_UNHALTED_CORE +Unused cycles ratio [%] = 100*UOPS_RETIRED_STALL_CYCLES/CPU_CLK_UNHALTED_CORE +Avg stall duration [cycles] = UOPS_RETIRED_STALL_CYCLES/UOPS_RETIRED_STALL_CYCLES:EDGEDETECT +- +This performance group returns the ratios of used and unused cycles regarding +the retirement stage in the pipeline (re-order buffer). Used cycles are all +cycles where uOPs are retired while unused cycles refer to pipeline stalls. +Moreover, the group calculates the average stall duration in cycles. diff --git a/collectors/likwid/groups/ivybridgeEP/BRANCH.txt b/collectors/likwid/groups/ivybridgeEP/BRANCH.txt new file mode 100644 index 0000000..b8d41b2 --- /dev/null +++ b/collectors/likwid/groups/ivybridgeEP/BRANCH.txt @@ -0,0 +1,31 @@ +SHORT Branch prediction miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 BR_INST_RETIRED_ALL_BRANCHES +PMC1 BR_MISP_RETIRED_ALL_BRANCHES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Branch rate PMC0/FIXC0 +Branch misprediction rate PMC1/FIXC0 +Branch misprediction ratio PMC1/PMC0 +Instructions per branch FIXC0/PMC0 + +LONG +Formulas: +Branch rate = BR_INST_RETIRED_ALL_BRANCHES/INSTR_RETIRED_ANY +Branch misprediction rate = BR_MISP_RETIRED_ALL_BRANCHES/INSTR_RETIRED_ANY +Branch misprediction ratio = BR_MISP_RETIRED_ALL_BRANCHES/BR_INST_RETIRED_ALL_BRANCHES +Instructions per branch = INSTR_RETIRED_ANY/BR_INST_RETIRED_ALL_BRANCHES +- +The rates state how often on average a branch or a mispredicted branch occurred +per instruction retired in total. The branch misprediction ratio sets directly +into relation what ratio of all branch instruction where mispredicted. +Instructions per branch is 1/branch rate. + diff --git a/collectors/likwid/groups/ivybridgeEP/CACHES.txt b/collectors/likwid/groups/ivybridgeEP/CACHES.txt new file mode 100644 index 0000000..fd1d43f --- /dev/null +++ b/collectors/likwid/groups/ivybridgeEP/CACHES.txt @@ -0,0 +1,121 @@ +SHORT Cache bandwidth in MBytes/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 L1D_REPLACEMENT +PMC1 L1D_M_EVICT +PMC2 L2_LINES_IN_ALL +PMC3 L2_LINES_OUT_DIRTY_ALL +CBOX0C0:STATE=0x3F LLC_LOOKUP_DATA_READ +CBOX1C0:STATE=0x3F LLC_LOOKUP_DATA_READ +CBOX2C0:STATE=0x3F LLC_LOOKUP_DATA_READ +CBOX3C0:STATE=0x3F LLC_LOOKUP_DATA_READ +CBOX4C0:STATE=0x3F LLC_LOOKUP_DATA_READ +CBOX5C0:STATE=0x3F LLC_LOOKUP_DATA_READ +CBOX6C0:STATE=0x3F LLC_LOOKUP_DATA_READ +CBOX7C0:STATE=0x3F LLC_LOOKUP_DATA_READ +CBOX8C0:STATE=0x3F LLC_LOOKUP_DATA_READ +CBOX9C0:STATE=0x3F LLC_LOOKUP_DATA_READ +CBOX10C0:STATE=0x3F LLC_LOOKUP_DATA_READ +CBOX11C0:STATE=0x3F LLC_LOOKUP_DATA_READ +CBOX12C0:STATE=0x3F LLC_LOOKUP_DATA_READ +CBOX13C0:STATE=0x3F LLC_LOOKUP_DATA_READ +CBOX14C0:STATE=0x3F LLC_LOOKUP_DATA_READ +CBOX0C1 LLC_VICTIMS_M_STATE +CBOX1C1 LLC_VICTIMS_M_STATE +CBOX2C1 LLC_VICTIMS_M_STATE +CBOX3C1 LLC_VICTIMS_M_STATE +CBOX4C1 LLC_VICTIMS_M_STATE +CBOX5C1 LLC_VICTIMS_M_STATE +CBOX6C1 LLC_VICTIMS_M_STATE +CBOX7C1 LLC_VICTIMS_M_STATE +CBOX8C1 LLC_VICTIMS_M_STATE +CBOX9C1 LLC_VICTIMS_M_STATE +CBOX10C1 LLC_VICTIMS_M_STATE +CBOX11C1 LLC_VICTIMS_M_STATE +CBOX12C1 LLC_VICTIMS_M_STATE +CBOX13C1 LLC_VICTIMS_M_STATE +CBOX14C1 LLC_VICTIMS_M_STATE +MBOX0C0 CAS_COUNT_RD +MBOX0C1 CAS_COUNT_WR +MBOX1C0 CAS_COUNT_RD +MBOX1C1 CAS_COUNT_WR +MBOX2C0 CAS_COUNT_RD +MBOX2C1 CAS_COUNT_WR +MBOX3C0 CAS_COUNT_RD +MBOX3C1 CAS_COUNT_WR +MBOX4C0 CAS_COUNT_RD +MBOX4C1 CAS_COUNT_WR +MBOX5C0 CAS_COUNT_RD +MBOX5C1 CAS_COUNT_WR +MBOX6C0 CAS_COUNT_RD +MBOX6C1 CAS_COUNT_WR +MBOX7C0 CAS_COUNT_RD +MBOX7C1 CAS_COUNT_WR + + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L2 to L1 load bandwidth [MBytes/s] 1.0E-06*PMC0*64.0/time +L2 to L1 load data volume [GBytes] 1.0E-09*PMC0*64.0 +L1 to L2 evict bandwidth [MBytes/s] 1.0E-06*PMC1*64.0/time +L1 to L2 evict data volume [GBytes] 1.0E-09*PMC1*64.0 +L1 to/from L2 bandwidth [MBytes/s] 1.0E-06*(PMC0+PMC1)*64.0/time +L1 to/from L2 data volume [GBytes] 1.0E-09*(PMC0+PMC1)*64.0 +L3 to L2 load bandwidth [MBytes/s] 1.0E-06*PMC2*64.0/time +L3 to L2 load data volume [GBytes] 1.0E-09*PMC2*64.0 +L2 to L3 evict bandwidth [MBytes/s] 1.0E-06*PMC3*64.0/time +L2 to L3 evict data volume [GBytes] 1.0E-09*PMC3*64.0 +L2 to/from L3 bandwidth [MBytes/s] 1.0E-06*(PMC2+PMC3)*64.0/time +L2 to/from L3 data volume [GBytes] 1.0E-09*(PMC2+PMC3)*64.0 +System to L3 bandwidth [MBytes/s] 1.0E-06*(CBOX0C0:STATE=0x3F+CBOX1C0:STATE=0x3F+CBOX2C0:STATE=0x3F+CBOX3C0:STATE=0x3F+CBOX4C0:STATE=0x3F+CBOX5C0:STATE=0x3F+CBOX6C0:STATE=0x3F+CBOX7C0:STATE=0x3F+CBOX8C0:STATE=0x3F+CBOX9C0:STATE=0x3F+CBOX10C0:STATE=0x3F+CBOX11C0:STATE=0x3F+CBOX12C0:STATE=0x3F+CBOX13C0:STATE=0x3F+CBOX14C0:STATE=0x3F)*64.0/time +System to L3 data volume [GBytes] 1.0E-09*(CBOX0C0:STATE=0x3F+CBOX1C0:STATE=0x3F+CBOX2C0:STATE=0x3F+CBOX3C0:STATE=0x3F+CBOX4C0:STATE=0x3F+CBOX5C0:STATE=0x3F+CBOX6C0:STATE=0x3F+CBOX7C0:STATE=0x3F+CBOX8C0:STATE=0x3F+CBOX9C0:STATE=0x3F+ CBOX10C0:STATE=0x3F+CBOX11C0:STATE=0x3F+CBOX12C0:STATE=0x3F+CBOX13C0:STATE=0x3F+CBOX14C0:STATE=0x3F)*64.0 +L3 to memory bandwidth [MBytes/s] 1.0E-06*(CBOX0C1+CBOX1C1+CBOX2C1+CBOX3C1+CBOX4C1+CBOX5C1+CBOX6C1+CBOX7C1+CBOX8C1+CBOX9C1+CBOX10C1+CBOX11C1+CBOX12C1+CBOX13C1+CBOX14C1)*64/time +L3 to memory data volume [GBytes] 1.0E-09*(CBOX0C1+CBOX1C1+CBOX2C1+CBOX3C1+CBOX4C1+CBOX5C1+CBOX6C1+CBOX7C1+CBOX8C1+CBOX9C1+CBOX10C1+CBOX11C1+CBOX12C1+CBOX13C1+CBOX14C1)*64 +L3 to/from system bandwidth [MBytes/s] 1.0E-06*(CBOX0C0:STATE=0x3F+CBOX1C0:STATE=0x3F+CBOX2C0:STATE=0x3F+CBOX3C0:STATE=0x3F+CBOX4C0:STATE=0x3F+CBOX5C0:STATE=0x3F+CBOX6C0:STATE=0x3F+CBOX7C0:STATE=0x3F+CBOX8C0:STATE=0x3F+CBOX9C0:STATE=0x3F+ CBOX10C0:STATE=0x3F+CBOX11C0:STATE=0x3F+CBOX12C0:STATE=0x3F+CBOX13C0:STATE=0x3F+CBOX14C0:STATE=0x3F+CBOX0C1+CBOX1C1+CBOX2C1+CBOX3C1+CBOX4C1+CBOX5C1+CBOX6C1+CBOX7C1+CBOX8C1+CBOX9C1+CBOX10C1+CBOX11C1+CBOX12C1+CBOX13C1+CBOX14C1)*64.0/time +L3 to/from system data volume [GBytes] 1.0E-09*(CBOX0C0:STATE=0x3F+CBOX1C0:STATE=0x3F+CBOX2C0:STATE=0x3F+CBOX3C0:STATE=0x3F+CBOX4C0:STATE=0x3F+CBOX5C0:STATE=0x3F+CBOX6C0:STATE=0x3F+CBOX7C0:STATE=0x3F+CBOX8C0:STATE=0x3F+CBOX9C0:STATE=0x3F+ CBOX10C0:STATE=0x3F+CBOX11C0:STATE=0x3F+CBOX12C0:STATE=0x3F+CBOX13C0:STATE=0x3F+CBOX14C0:STATE=0x3F+CBOX0C1+CBOX1C1+CBOX2C1+CBOX3C1+CBOX4C1+CBOX5C1+CBOX6C1+CBOX7C1+CBOX8C1+CBOX9C1+CBOX10C1+CBOX11C1+CBOX12C1+CBOX13C1+CBOX14C1)*64.0 +Memory read bandwidth [MBytes/s] 1.0E-06*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX6C0+MBOX7C0)*64.0/time +Memory read data volume [GBytes] 1.0E-09*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX6C0+MBOX7C0)*64.0 +Memory write bandwidth [MBytes/s] 1.0E-06*(MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1+MBOX6C1+MBOX7C1)*64.0/time +Memory write data volume [GBytes] 1.0E-09*(MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1+MBOX6C1+MBOX7C1)*64.0 +Memory bandwidth [MBytes/s] 1.0E-06*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX6C0+MBOX7C0+MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1+MBOX6C1+MBOX7C1)*64.0/time +Memory data volume [GBytes] 1.0E-09*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX6C0+MBOX7C0+MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1+MBOX6C1+MBOX7C1)*64.0 + +LONG +Formulas: +L2 to L1 load bandwidth [MBytes/s] = 1.0E-06*L1D_REPLACEMENT*64/time +L2 to L1 load data volume [GBytes] = 1.0E-09*L1D_REPLACEMENT*64 +L1 to L2 evict bandwidth [MBytes/s] = 1.0E-06*L1D_M_EVICT*64/time +L1 to L2 evict data volume [GBytes] = 1.0E-09*L1D_M_EVICT*64 +L1 to/from L2 bandwidth [MBytes/s] = 1.0E-06*(L1D_REPLACEMENT+L1D_M_EVICT)*64/time +L1 to/from L2 data volume [GBytes] = 1.0E-09*(L1D_REPLACEMENT+L1D_M_EVICT)*64 +L3 to L2 load bandwidth [MBytes/s] = 1.0E-06*L2_LINES_IN_ALL*64/time +L3 to L2 load data volume [GBytes] = 1.0E-09*L2_LINES_IN_ALL*64 +L2 to L3 evict bandwidth [MBytes/s] = 1.0E-06*L2_TRANS_L2_WB*64/time +L2 to L3 evict data volume [GBytes] = 1.0E-09*L2_TRANS_L2_WB*64 +L2 to/from L3 bandwidth [MBytes/s] = 1.0E-06*(L2_LINES_IN_ALL+L2_TRANS_L2_WB)*64/time +L2 to/from L3 data volume [GBytes] = 1.0E-09*(L2_LINES_IN_ALL+L2_TRANS_L2_WB)*64 +System to L3 bandwidth [MBytes/s] = 1.0E-06*(SUM(LLC_LOOKUP_DATA_READ:STATE=0x3F))*64/time +System to L3 data volume [GBytes] = 1.0E-09*(SUM(LLC_LOOKUP_DATA_READ:STATE=0x3F))*64 +L3 to system bandwidth [MBytes/s] = 1.0E-06*(SUM(LLC_VICTIMS_M_STATE))*64/time +L3 to system data volume [GBytes] = 1.0E-09*(SUM(LLC_VICTIMS_M_STATE))*64 +L3 to/from system bandwidth [MBytes/s] = 1.0E-06*(SUM(LLC_LOOKUP_DATA_READ:STATE=0x3F)+SUM(LLC_VICTIMS_M_STATE))*64/time +L3 to/from system data volume [GBytes] = 1.0E-09*(SUM(LLC_LOOKUP_DATA_READ:STATE=0x3F)+SUM(LLC_VICTIMS_M_STATE))*64 +Memory read bandwidth [MBytes/s] = 1.0E-06*(SUM(CAS_COUNT_RD))*64.0/time +Memory read data volume [GBytes] = 1.0E-09*(SUM(CAS_COUNT_RD))*64.0 +Memory write bandwidth [MBytes/s] = 1.0E-06*(SUM(CAS_COUNT_WR))*64.0/time +Memory write data volume [GBytes] = 1.0E-09*(SUM(CAS_COUNT_WR))*64.0 +Memory bandwidth [MBytes/s] = 1.0E-06*(SUM(CAS_COUNT_RD)+SUM(CAS_COUNT_WR))*64.0/time +Memory data volume [GBytes] = 1.0E-09*(SUM(CAS_COUNT_RD)+SUM(CAS_COUNT_WR))*64.0 +- +Group to measure cache transfers between L1 and Memory. Please notice that the +L3 to/from system metrics contain any traffic to the system (memory, +Intel QPI, etc.) but don't seem to handle anything because commonly memory read +bandwidth and L3 to L2 bandwidth is higher as the memory to L3 bandwidth. + diff --git a/collectors/likwid/groups/ivybridgeEP/CBOX.txt b/collectors/likwid/groups/ivybridgeEP/CBOX.txt new file mode 100644 index 0000000..5c87149 --- /dev/null +++ b/collectors/likwid/groups/ivybridgeEP/CBOX.txt @@ -0,0 +1,55 @@ +SHORT CBOX related data and metrics + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +CBOX0C0 LLC_VICTIMS_M_STATE +CBOX1C0 LLC_VICTIMS_M_STATE +CBOX2C0 LLC_VICTIMS_M_STATE +CBOX3C0 LLC_VICTIMS_M_STATE +CBOX4C0 LLC_VICTIMS_M_STATE +CBOX5C0 LLC_VICTIMS_M_STATE +CBOX6C0 LLC_VICTIMS_M_STATE +CBOX7C0 LLC_VICTIMS_M_STATE +CBOX8C0 LLC_VICTIMS_M_STATE +CBOX9C0 LLC_VICTIMS_M_STATE +CBOX10C0 LLC_VICTIMS_M_STATE +CBOX11C0 LLC_VICTIMS_M_STATE +CBOX12C0 LLC_VICTIMS_M_STATE +CBOX13C0 LLC_VICTIMS_M_STATE +CBOX14C0 LLC_VICTIMS_M_STATE +CBOX0C1:STATE=0x1 LLC_LOOKUP_ANY +CBOX1C1:STATE=0x1 LLC_LOOKUP_ANY +CBOX2C1:STATE=0x1 LLC_LOOKUP_ANY +CBOX3C1:STATE=0x1 LLC_LOOKUP_ANY +CBOX4C1:STATE=0x1 LLC_LOOKUP_ANY +CBOX5C1:STATE=0x1 LLC_LOOKUP_ANY +CBOX6C1:STATE=0x1 LLC_LOOKUP_ANY +CBOX7C1:STATE=0x1 LLC_LOOKUP_ANY +CBOX8C1:STATE=0x1 LLC_LOOKUP_ANY +CBOX9C1:STATE=0x1 LLC_LOOKUP_ANY +CBOX10C1:STATE=0x1 LLC_LOOKUP_ANY +CBOX11C1:STATE=0x1 LLC_LOOKUP_ANY +CBOX12C1:STATE=0x1 LLC_LOOKUP_ANY +CBOX13C1:STATE=0x1 LLC_LOOKUP_ANY +CBOX14C1:STATE=0x1 LLC_LOOKUP_ANY + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +LLC misses per instruction (CBOX0C0+CBOX1C0+CBOX2C0+CBOX3C0+CBOX4C0+CBOX5C0+CBOX6C0+CBOX7C0+CBOX8C0+CBOX9C0+CBOX10C0+CBOX11C0+CBOX12C0+CBOX13C0+CBOX14C0)/FIXC0 +LLC data written to MEM [MBytes] 1E-6*(CBOX0C1:STATE=0x1+CBOX1C1:STATE=0x1+CBOX2C1:STATE=0x1+CBOX3C1:STATE=0x1+CBOX4C1:STATE=0x1+CBOX5C1:STATE=0x1+CBOX6C1:STATE=0x1+CBOX7C1:STATE=0x1+CBOX8C1:STATE=0x1+CBOX9C1:STATE=0x1+CBOX10C1:STATE=0x1+CBOX11C1:STATE=0x1+CBOX12C1:STATE=0x1+CBOX13C1:STATE=0x1+CBOX14C1:STATE=0x1)*64 + + +LONG +Formulas: +LLC misses per instruction = sum(LLC_VICTIMS_M_STATE)/INSTR_RETIRED_ANY +LLC data written to MEM [MBytes] = sum(LLC_LOOKUP_ANY:STATE=0x1)*64*1E-6 +-- +The CBOXes mediate the traffic from the L2 cache to the segmented L3 cache. Each +CBOX is responsible for one segment (2.5 MByte). The boxes maintain the coherence between all +CPU cores of the socket. Depending on the CPU core count, some CBOXes are not attached +to a 2.5 MByte slice but are still active and track the traffic. diff --git a/collectors/likwid/groups/ivybridgeEP/CLOCK.txt b/collectors/likwid/groups/ivybridgeEP/CLOCK.txt new file mode 100644 index 0000000..fb19101 --- /dev/null +++ b/collectors/likwid/groups/ivybridgeEP/CLOCK.txt @@ -0,0 +1,26 @@ +SHORT Power and Energy consumption + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PWR0 PWR_PKG_ENERGY +UBOXFIX UNCORE_CLOCK + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +Uncore Clock [MHz] 1.E-06*UBOXFIX/time +CPI FIXC1/FIXC0 +Energy [J] PWR0 +Power [W] PWR0/time + +LONG +Formulas: +Power = PWR_PKG_ENERGY / time +Uncore Clock [MHz] = 1.E-06 * UNCORE_CLOCK / time +- +IvyBridge implements the new RAPL interface. This interface enables to +monitor the consumed energy on the package (socket) level. + diff --git a/collectors/likwid/groups/ivybridgeEP/CYCLE_ACTIVITY.txt b/collectors/likwid/groups/ivybridgeEP/CYCLE_ACTIVITY.txt new file mode 100644 index 0000000..c432a44 --- /dev/null +++ b/collectors/likwid/groups/ivybridgeEP/CYCLE_ACTIVITY.txt @@ -0,0 +1,38 @@ +SHORT Cycle Activities + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 CYCLE_ACTIVITY_CYCLES_L2_PENDING +PMC1 CYCLE_ACTIVITY_CYCLES_LDM_PENDING +PMC2 CYCLE_ACTIVITY_CYCLES_L1D_PENDING +PMC3 CYCLE_ACTIVITY_CYCLES_NO_EXECUTE + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Cycles without execution [%] (PMC3/FIXC1)*100 +Cycles without execution due to L1D [%] (PMC2/FIXC1)*100 +Cycles without execution due to L2 [%] (PMC0/FIXC1)*100 +Cycles without execution due to memory loads [%] (PMC1/FIXC1)*100 + +LONG +Formulas: +Cycles without execution [%] = CYCLE_ACTIVITY_CYCLES_NO_EXECUTE/CPU_CLK_UNHALTED_CORE*100 +Cycles with stalls due to L1D [%] = CYCLE_ACTIVITY_CYCLES_L1D_PENDING/CPU_CLK_UNHALTED_CORE*100 +Cycles with stalls due to L2 [%] = CYCLE_ACTIVITY_CYCLES_L2_PENDING/CPU_CLK_UNHALTED_CORE*100 +Cycles without execution due to memory loads [%] = CYCLE_ACTIVITY_CYCLES_LDM_PENDING/CPU_CLK_UNHALTED_CORE*100 +-- +This performance group measures the cycles while waiting for data from the cache +and memory hierarchy. +CYCLE_ACTIVITY_CYCLES_NO_EXECUTE: Counts number of cycles nothing is executed on +any execution port. +CYCLE_ACTIVITY_CYCLES_L1D_PENDING: Cycles while L1 cache miss demand load is +outstanding. +CYCLE_ACTIVITY_CYCLES_L2_PENDING: Cycles while L2 cache miss demand load is +outstanding. +CYCLE_ACTIVITY_CYCLES_LDM_PENDING: Cycles while memory subsystem has an +outstanding load. diff --git a/collectors/likwid/groups/ivybridgeEP/CYCLE_STALLS.txt b/collectors/likwid/groups/ivybridgeEP/CYCLE_STALLS.txt new file mode 100644 index 0000000..795aeb9 --- /dev/null +++ b/collectors/likwid/groups/ivybridgeEP/CYCLE_STALLS.txt @@ -0,0 +1,45 @@ +SHORT Cycle Activities (Stalls) + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 CYCLE_ACTIVITY_STALLS_L2_PENDING +PMC1 CYCLE_ACTIVITY_STALLS_LDM_PENDING +PMC2 CYCLE_ACTIVITY_STALLS_L1D_PENDING +PMC3 CYCLE_ACTIVITY_STALLS_TOTAL + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Total execution stalls PMC3 +Stalls caused by L1D misses [%] (PMC2/PMC3)*100 +Stalls caused by L2 misses [%] (PMC0/PMC3)*100 +Stalls caused by memory loads [%] (PMC1/PMC3)*100 +Execution stall rate [%] (PMC3/FIXC1)*100 +Stalls caused by L1D misses rate [%] (PMC2/FIXC1)*100 +Stalls caused by L2 misses rate [%] (PMC0/FIXC1)*100 +Stalls caused by memory loads rate [%] (PMC1/FIXC1)*100 + +LONG +Formulas: +Total execution stalls = CYCLE_ACTIVITY_STALLS_TOTAL +Stalls caused by L1D misses [%] = (CYCLE_ACTIVITY_STALLS_L1D_PENDING/CYCLE_ACTIVITY_STALLS_TOTAL)*100 +Stalls caused by L2 misses [%] = (CYCLE_ACTIVITY_STALLS_L2_PENDING/CYCLE_ACTIVITY_STALLS_TOTAL)*100 +Stalls caused by memory loads [%] = (CYCLE_ACTIVITY_STALLS_LDM_PENDING/CYCLE_ACTIVITY_STALLS_TOTAL)*100 +Execution stall rate [%] = (CYCLE_ACTIVITY_STALLS_TOTAL/CPU_CLK_UNHALTED_CORE)*100 +Stalls caused by L1D misses rate [%] = (CYCLE_ACTIVITY_STALLS_L1D_PENDING/CPU_CLK_UNHALTED_CORE)*100 +Stalls caused by L2 misses rate [%] = (CYCLE_ACTIVITY_STALLS_L2_PENDING/CPU_CLK_UNHALTED_CORE)*100 +Stalls caused by memory loads rate [%] = (CYCLE_ACTIVITY_STALLS_LDM_PENDING/CPU_CLK_UNHALTED_CORE)*100 +-- +This performance group measures the stalls caused by data traffic in the cache +hierarchy. +CYCLE_ACTIVITY_STALLS_TOTAL: Total execution stalls. +CYCLE_ACTIVITY_STALLS_L1D_PENDING: Execution stalls while L1 cache miss demand +load is outstanding. +CYCLE_ACTIVITY_STALLS_L2_PENDING: Execution stalls while L2 cache miss demand +load is outstanding. +CYCLE_ACTIVITY_STALLS_LDM_PENDING: Execution stalls while memory subsystem has +an outstanding load. diff --git a/collectors/likwid/groups/ivybridgeEP/DATA.txt b/collectors/likwid/groups/ivybridgeEP/DATA.txt new file mode 100644 index 0000000..967cbad --- /dev/null +++ b/collectors/likwid/groups/ivybridgeEP/DATA.txt @@ -0,0 +1,22 @@ +SHORT Load to store ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 MEM_UOPS_RETIRED_LOADS +PMC1 MEM_UOPS_RETIRED_STORES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Load to store ratio PMC0/PMC1 + +LONG +Formulas: +Load to store ratio = MEM_UOPS_RETIRED_LOADS/MEM_UOPS_RETIRED_STORES +- +This is a metric to determine your load to store ratio. + diff --git a/collectors/likwid/groups/ivybridgeEP/DIVIDE.txt b/collectors/likwid/groups/ivybridgeEP/DIVIDE.txt new file mode 100644 index 0000000..f8cb0b3 --- /dev/null +++ b/collectors/likwid/groups/ivybridgeEP/DIVIDE.txt @@ -0,0 +1,24 @@ +SHORT Divide unit information + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 ARITH_NUM_DIV +PMC1 ARITH_FPU_DIV_ACTIVE + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Number of divide ops PMC0 +Avg. divide unit usage duration PMC1/PMC0 + +LONG +Formulas: +Number of divide ops = ARITH_NUM_DIV +Avg. divide unit usage duration = ARITH_FPU_DIV_ACTIVE/ARITH_NUM_DIV +- +This performance group measures the average latency of divide operations diff --git a/collectors/likwid/groups/ivybridgeEP/ENERGY.txt b/collectors/likwid/groups/ivybridgeEP/ENERGY.txt new file mode 100644 index 0000000..74c16bb --- /dev/null +++ b/collectors/likwid/groups/ivybridgeEP/ENERGY.txt @@ -0,0 +1,33 @@ +SHORT Power and Energy consumption + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +TMP0 TEMP_CORE +PWR0 PWR_PKG_ENERGY +PWR1 PWR_PP0_ENERGY +PWR3 PWR_DRAM_ENERGY + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Temperature [C] TMP0 +Energy [J] PWR0 +Power [W] PWR0/time +Energy PP0 [J] PWR1 +Power PP0 [W] PWR1/time +Energy DRAM [J] PWR3 +Power DRAM [W] PWR3/time + +LONG +Formulas: +Power = PWR_PKG_ENERGY / time +Power PP0 = PWR_PP0_ENERGY / time +Power DRAM = PWR_DRAM_ENERGY / time +- +IvyBridge implements the new RAPL interface. This interface enables to +monitor the consumed energy on the package (socket), the PP0 domain +and DRAM level. The PP0 domain often refers to only the CPU cores. diff --git a/collectors/likwid/groups/ivybridgeEP/FALSE_SHARE.txt b/collectors/likwid/groups/ivybridgeEP/FALSE_SHARE.txt new file mode 100644 index 0000000..5e28a15 --- /dev/null +++ b/collectors/likwid/groups/ivybridgeEP/FALSE_SHARE.txt @@ -0,0 +1,32 @@ +SHORT False sharing + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 MEM_LOAD_UOPS_LLC_HIT_RETIRED_XSNP_HITM +PMC1 MEM_LOAD_UOPS_LLC_MISS_RETIRED_REMOTE_HITM +PMC2 MEM_LOAD_UOPS_RETIRED_ALL + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Local LLC false sharing [MByte] 1.E-06*PMC0*64 +Local LLC false sharing rate PMC0/PMC2 +Remote LLC false sharing [MByte] 1.E-06*PMC1*64 +Remote LLC false sharing rate PMC1/PMC2 + +LONG +Formulas: +Local LLC false sharing [MByte] = 1.E-06*MEM_LOAD_UOPS_LLC_HIT_RETIRED_XSNP_HITM*64 +Local LLC false sharing rate = MEM_LOAD_UOPS_LLC_HIT_RETIRED_XSNP_HITM/MEM_LOAD_UOPS_RETIRED_ALL +Remote LLC false sharing [MByte] = 1.E-06*MEM_LOAD_UOPS_LLC_MISS_RETIRED_REMOTE_HITM*64 +Remote LLC false sharing rate = MEM_LOAD_UOPS_LLC_MISS_RETIRED_REMOTE_HITM/MEM_LOAD_UOPS_RETIRED_ALL +- +False-sharing of cache lines can dramatically reduce the performance of an +application. This performance group measures the L3 traffic induced by false-sharing. +The false-sharing rate uses all memory loads as reference. +For systems with multiple CPU sockets, this performance group also measures the +false-sharing of cache lines over socket boundaries. diff --git a/collectors/likwid/groups/ivybridgeEP/FLOPS_AVX.txt b/collectors/likwid/groups/ivybridgeEP/FLOPS_AVX.txt new file mode 100644 index 0000000..0ad669f --- /dev/null +++ b/collectors/likwid/groups/ivybridgeEP/FLOPS_AVX.txt @@ -0,0 +1,26 @@ +SHORT Packed AVX MFLOP/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 SIMD_FP_256_PACKED_SINGLE +PMC1 SIMD_FP_256_PACKED_DOUBLE + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Packed SP [MFLOP/s] 1.0E-06*(PMC0*8.0)/time +Packed DP [MFLOP/s] 1.0E-06*(PMC1*4.0)/time + +LONG +Formulas: +Packed SP [MFLOP/s] = 1.0E-06*(SIMD_FP_256_PACKED_SINGLE*8)/runtime +Packed DP [MFLOP/s] = 1.0E-06*(SIMD_FP_256_PACKED_DOUBLE*4)/runtime +- +Packed 32b AVX FLOPs rates. Please note that the current FLOP measurements on +IvyBridge are potentially wrong. +So you cannot trust these counters at the moment! + diff --git a/collectors/likwid/groups/ivybridgeEP/FLOPS_DP.txt b/collectors/likwid/groups/ivybridgeEP/FLOPS_DP.txt new file mode 100644 index 0000000..e737098 --- /dev/null +++ b/collectors/likwid/groups/ivybridgeEP/FLOPS_DP.txt @@ -0,0 +1,33 @@ +SHORT Double Precision MFLOP/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 FP_COMP_OPS_EXE_SSE_FP_PACKED_DOUBLE +PMC1 FP_COMP_OPS_EXE_SSE_FP_SCALAR_DOUBLE +PMC2 SIMD_FP_256_PACKED_DOUBLE + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +DP [MFLOP/s] 1.0E-06*(PMC0*2.0+PMC1+PMC2*4.0)/time +AVX DP [MFLOP/s] 1.0E-06*(PMC2*4.0)/time +Packed [MUOPS/s] 1.0E-06*(PMC0+PMC2)/time +Scalar [MUOPS/s] 1.0E-06*PMC1/time +Vectorization ratio 100*(PMC0+PMC2)/(PMC0+PMC1+PMC2) + +LONG +Formulas: +DP [MFLOP/s] = 1.0E-06*(FP_COMP_OPS_EXE_SSE_FP_PACKED*2+FP_COMP_OPS_EXE_SSE_FP_SCALAR+SIMD_FP_256_PACKED_DOUBLE*4)/runtime +AVX DP [MFLOP/s] = 1.0E-06*(SIMD_FP_256_PACKED_DOUBLE*4)/runtime +Packed [MUOPS/s] = 1.0E-06*(FP_COMP_OPS_EXE_SSE_FP_PACKED_DOUBLE+SIMD_FP_256_PACKED_DOUBLE)/runtime +Scalar [MUOPS/s] = 1.0E-06*FP_COMP_OPS_EXE_SSE_FP_SCALAR_DOUBLE/runtime +Vectorization ratio = 100*(FP_COMP_OPS_EXE_SSE_FP_PACKED_DOUBLE+SIMD_FP_256_PACKED_DOUBLE)/(FP_COMP_OPS_EXE_SSE_FP_SCALAR_DOUBLE+FP_COMP_OPS_EXE_SSE_FP_PACKED_DOUBLE+SIMD_FP_256_PACKED_DOUBLE) +- +SSE scalar and packed double precision FLOP rates. Please note that the current +FLOP measurements on IvyBridge are potentially wrong. +So you cannot trust these counters at the moment! + diff --git a/collectors/likwid/groups/ivybridgeEP/FLOPS_SP.txt b/collectors/likwid/groups/ivybridgeEP/FLOPS_SP.txt new file mode 100644 index 0000000..7483722 --- /dev/null +++ b/collectors/likwid/groups/ivybridgeEP/FLOPS_SP.txt @@ -0,0 +1,33 @@ +SHORT Single Precision MFLOP/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 FP_COMP_OPS_EXE_SSE_FP_PACKED_SINGLE +PMC1 FP_COMP_OPS_EXE_SSE_FP_SCALAR_SINGLE +PMC2 SIMD_FP_256_PACKED_SINGLE + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +SP [MFLOP/s] 1.0E-06*(PMC0*4.0+PMC1+PMC2*8.0)/time +AVX SP [MFLOP/s] 1.0E-06*(PMC2*8.0)/time +Packed [MUOPS/s] 1.0E-06*(PMC0+PMC2)/time +Scalar [MUOPS/s] 1.0E-06*PMC1/time +Vectorization ratio 100*(PMC0+PMC2)/(PMC0+PMC1+PMC2) + +LONG +Formulas: +SP [MFLOP/s] = 1.0E-06*(FP_COMP_OPS_EXE_SSE_FP_PACKED*4+FP_COMP_OPS_EXE_SSE_FP_SCALAR+SIMD_FP_256_PACKED_SINGLE*8)/runtime +AVX SP [MFLOP/s] = 1.0E-06*(SIMD_FP_256_PACKED_SINGLE*8)/runtime +Packed [MUOPS/s] = 1.0E-06*(FP_COMP_OPS_EXE_SSE_FP_PACKED_SINGLE+SIMD_FP_256_PACKED_SINGLE)/runtime +Scalar [MUOPS/s] = 1.0E-06*FP_COMP_OPS_EXE_SSE_FP_SCALAR_SINGLE/runtime +Vectorization ratio = 100*(FP_COMP_OPS_EXE_SSE_FP_PACKED_SINGLE+SIMD_FP_256_PACKED_SINGLE)/(FP_COMP_OPS_EXE_SSE_FP_SCALAR_SINGLE+FP_COMP_OPS_EXE_SSE_FP_PACKED_SINGLE+SIMD_FP_256_PACKED_SINGLE) +- +SSE scalar and packed single precision FLOP rates. Please note that the current +FLOP measurements on IvyBridge are potentially wrong. +So you cannot trust these counters at the moment! + diff --git a/collectors/likwid/groups/ivybridgeEP/ICACHE.txt b/collectors/likwid/groups/ivybridgeEP/ICACHE.txt new file mode 100644 index 0000000..f1e2335 --- /dev/null +++ b/collectors/likwid/groups/ivybridgeEP/ICACHE.txt @@ -0,0 +1,33 @@ +SHORT Instruction cache miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 ICACHE_ACCESSES +PMC1 ICACHE_MISSES +PMC2 ICACHE_IFETCH_STALL +PMC3 ILD_STALL_IQ_FULL + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L1I request rate PMC0/FIXC0 +L1I miss rate PMC1/FIXC0 +L1I miss ratio PMC1/PMC0 +L1I stalls PMC2 +L1I stall rate PMC2/FIXC0 +L1I queue full stalls PMC3 +L1I queue full stall rate PMC3/FIXC0 + +LONG +Formulas: +L1I request rate = ICACHE_ACCESSES / INSTR_RETIRED_ANY +L1I miss rate = ICACHE_MISSES / INSTR_RETIRED_ANY +L1I miss ratio = ICACHE_MISSES / ICACHE_ACCESSES +L1I stalls = ICACHE_IFETCH_STALL +L1I stall rate = ICACHE_IFETCH_STALL / INSTR_RETIRED_ANY +- +This group measures some L1 instruction cache metrics. diff --git a/collectors/likwid/groups/ivybridgeEP/L2.txt b/collectors/likwid/groups/ivybridgeEP/L2.txt new file mode 100644 index 0000000..376e974 --- /dev/null +++ b/collectors/likwid/groups/ivybridgeEP/L2.txt @@ -0,0 +1,38 @@ +SHORT L2 cache bandwidth in MBytes/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 L1D_REPLACEMENT +PMC1 L1D_M_EVICT +PMC2 ICACHE_MISSES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L2D load bandwidth [MBytes/s] 1.0E-06*PMC0*64.0/time +L2D load data volume [GBytes] 1.0E-09*PMC0*64.0 +L2D evict bandwidth [MBytes/s] 1.0E-06*PMC1*64.0/time +L2D evict data volume [GBytes] 1.0E-09*PMC1*64.0 +L2 bandwidth [MBytes/s] 1.0E-06*(PMC0+PMC1+PMC2)*64.0/time +L2 data volume [GBytes] 1.0E-09*(PMC0+PMC1+PMC2)*64.0 + +LONG +Formulas: +L2D load bandwidth [MBytes/s] = 1.0E-06*L1D_REPLACEMENT*64.0/time +L2D load data volume [GBytes] = 1.0E-09*L1D_REPLACEMENT*64.0 +L2D evict bandwidth [MBytes/s] = 1.0E-06*L1D_M_EVICT*64.0/time +L2D evict data volume [GBytes] = 1.0E-09*L1D_M_EVICT*64.0 +L2 bandwidth [MBytes/s] = 1.0E-06*(L1D_REPLACEMENT+L1D_M_EVICT+ICACHE_MISSES)*64/time +L2 data volume [GBytes] = 1.0E-09*(L1D_REPLACEMENT+L1D_M_EVICT+ICACHE_MISSES)*64 +- +Profiling group to measure L2 cache bandwidth. The bandwidth is computed by the +number of cache line allocated in the L1 and the number of modified cache lines +evicted from the L1. The group also outputs total data volume transferred between +L2 and L1. Note that this bandwidth also includes data transfers due to a write +allocate load on a store miss in L1 and cache lines transferred it the instruction +cache. + diff --git a/collectors/likwid/groups/ivybridgeEP/L2CACHE.txt b/collectors/likwid/groups/ivybridgeEP/L2CACHE.txt new file mode 100644 index 0000000..9b5dd4b --- /dev/null +++ b/collectors/likwid/groups/ivybridgeEP/L2CACHE.txt @@ -0,0 +1,34 @@ +SHORT L2 cache miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 L2_TRANS_ALL_REQUESTS +PMC1 L2_RQSTS_MISS + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L2 request rate PMC0/FIXC0 +L2 miss rate PMC1/FIXC0 +L2 miss ratio PMC1/PMC0 + +LONG +Formulas: +L2 request rate = L2_TRANS_ALL_REQUESTS/INSTR_RETIRED_ANY +L2 miss rate = L2_RQSTS_MISS/INSTR_RETIRED_ANY +L2 miss ratio = L2_RQSTS_MISS/L2_TRANS_ALL_REQUESTS +- +This group measures the locality of your data accesses with regard to the +L2 cache. L2 request rate tells you how data intensive your code is +or how many data accesses you have on average per instruction. +The L2 miss rate gives a measure how often it was necessary to get +cache lines from memory. And finally L2 miss ratio tells you how many of your +memory references required a cache line to be loaded from a higher level. +While the# data cache miss rate might be given by your algorithm you should +try to get data cache miss ratio as low as possible by increasing your cache reuse. + + diff --git a/collectors/likwid/groups/ivybridgeEP/L3.txt b/collectors/likwid/groups/ivybridgeEP/L3.txt new file mode 100644 index 0000000..f0a8aad --- /dev/null +++ b/collectors/likwid/groups/ivybridgeEP/L3.txt @@ -0,0 +1,36 @@ +SHORT L3 cache bandwidth in MBytes/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 L2_LINES_IN_ALL +PMC1 L2_LINES_OUT_DIRTY_ALL + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L3 load bandwidth [MBytes/s] 1.0E-06*PMC0*64.0/time +L3 load data volume [GBytes] 1.0E-09*PMC0*64.0 +L3 evict bandwidth [MBytes/s] 1.0E-06*PMC1*64.0/time +L3 evict data volume [GBytes] 1.0E-09*PMC1*64.0 +L3 bandwidth [MBytes/s] 1.0E-06*(PMC0+PMC1)*64.0/time +L3 data volume [GBytes] 1.0E-09*(PMC0+PMC1)*64.0 + +LONG +Formulas: +L3 load bandwidth [MBytes/s] = 1.0E-06*L2_LINES_IN_ALL*64.0/time +L3 load data volume [GBytes] = 1.0E-09*L2_LINES_IN_ALL*64.0 +L3 evict bandwidth [MBytes/s] = 1.0E-06*L2_LINES_OUT_DIRTY_ALL*64.0/time +L3 evict data volume [GBytes] = 1.0E-09*L2_LINES_OUT_DIRTY_ALL*64.0 +L3 bandwidth [MBytes/s] = 1.0E-06*(L2_LINES_IN_ALL+L2_LINES_OUT_DIRTY_ALL)*64/time +L3 data volume [GBytes] = 1.0E-09*(L2_LINES_IN_ALL+L2_LINES_OUT_DIRTY_ALL)*64 +- +Profiling group to measure L3 cache bandwidth. The bandwidth is computed by the +number of cache line allocated in the L2 and the number of modified cache lines +evicted from the L2. This group also output data volume transferred between the +L3 and measured cores L2 caches. Note that this bandwidth also includes data +transfers due to a write allocate load on a store miss in L2. + diff --git a/collectors/likwid/groups/ivybridgeEP/L3CACHE.txt b/collectors/likwid/groups/ivybridgeEP/L3CACHE.txt new file mode 100644 index 0000000..9f3036f --- /dev/null +++ b/collectors/likwid/groups/ivybridgeEP/L3CACHE.txt @@ -0,0 +1,36 @@ +SHORT L3 cache miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 MEM_LOAD_UOPS_RETIRED_L3_ALL +PMC1 MEM_LOAD_UOPS_RETIRED_L3_MISS +PMC2 UOPS_RETIRED_ALL + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L3 request rate (PMC0)/PMC2 +L3 miss rate PMC1/PMC2 +L3 miss ratio PMC1/PMC0 + +LONG +Formulas: +L3 request rate = MEM_LOAD_UOPS_RETIRED_L3_ALL/UOPS_RETIRED_ALL +L3 miss rate = MEM_LOAD_UOPS_RETIRED_L3_MISS/UOPS_RETIRED_ALL +L3 miss ratio = MEM_LOAD_UOPS_RETIRED_L3_MISS/MEM_LOAD_UOPS_RETIRED_L3_ALL +- +This group measures the locality of your data accesses with regard to the +L3 cache. L3 request rate tells you how data intensive your code is +or how many data accesses you have on average per instruction. +The L3 miss rate gives a measure how often it was necessary to get +cache lines from memory. And finally L3 miss ratio tells you how many of your +memory references required a cache line to be loaded from a higher level. +While the# data cache miss rate might be given by your algorithm you should +try to get data cache miss ratio as low as possible by increasing your cache reuse. + + diff --git a/collectors/likwid/groups/ivybridgeEP/MEM.txt b/collectors/likwid/groups/ivybridgeEP/MEM.txt new file mode 100644 index 0000000..fd80c2c --- /dev/null +++ b/collectors/likwid/groups/ivybridgeEP/MEM.txt @@ -0,0 +1,49 @@ +SHORT Main memory bandwidth in MBytes/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +MBOX0C0 CAS_COUNT_RD +MBOX0C1 CAS_COUNT_WR +MBOX1C0 CAS_COUNT_RD +MBOX1C1 CAS_COUNT_WR +MBOX2C0 CAS_COUNT_RD +MBOX2C1 CAS_COUNT_WR +MBOX3C0 CAS_COUNT_RD +MBOX3C1 CAS_COUNT_WR +MBOX4C0 CAS_COUNT_RD +MBOX4C1 CAS_COUNT_WR +MBOX5C0 CAS_COUNT_RD +MBOX5C1 CAS_COUNT_WR +MBOX6C0 CAS_COUNT_RD +MBOX6C1 CAS_COUNT_WR +MBOX7C0 CAS_COUNT_RD +MBOX7C1 CAS_COUNT_WR + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Memory read bandwidth [MBytes/s] 1.0E-06*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX6C0+MBOX7C0)*64.0/time +Memory read data volume [GBytes] 1.0E-09*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX6C0+MBOX7C0)*64.0 +Memory write bandwidth [MBytes/s] 1.0E-06*(MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1+MBOX6C1+MBOX7C1)*64.0/time +Memory write data volume [GBytes] 1.0E-09*(MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1+MBOX6C1+MBOX7C1)*64.0 +Memory bandwidth [MBytes/s] 1.0E-06*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX6C0+MBOX7C0+MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1+MBOX6C1+MBOX7C1)*64.0/time +Memory data volume [GBytes] 1.0E-09*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX6C0+MBOX7C0+MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1+MBOX6C1+MBOX7C1)*64.0 + +LONG +Formulas: +Memory read bandwidth [MBytes/s] = 1.0E-06*(SUM(MBOXxC0))*64.0/time +Memory read data volume [GBytes] = 1.0E-09*(SUM(MBOXxC0))*64.0 +Memory write bandwidth [MBytes/s] = 1.0E-06*(SUM(MBOXxC1))*64.0/time +Memory write data volume [GBytes] = 1.0E-09*(SUM(MBOXxC1))*64.0 +Memory bandwidth [MBytes/s] = 1.0E-06*(SUM(MBOXxC0)+SUM(MBOXxC1))*64.0/time +Memory data volume [GBytes] = 1.0E-09*(SUM(MBOXxC0)+SUM(MBOXxC1))*64.0 +- +Profiling group to measure memory bandwidth drawn by all cores of a socket. +Since this group is based on Uncore events it is only possible to measure on a +per socket base. Some of the counters may not be available on your system. +Also outputs total data volume transferred from main memory. + diff --git a/collectors/likwid/groups/ivybridgeEP/MEM_DP.txt b/collectors/likwid/groups/ivybridgeEP/MEM_DP.txt new file mode 100644 index 0000000..eff1677 --- /dev/null +++ b/collectors/likwid/groups/ivybridgeEP/MEM_DP.txt @@ -0,0 +1,75 @@ +SHORT Power and Energy consumption + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PWR0 PWR_PKG_ENERGY +PWR3 PWR_DRAM_ENERGY +PMC0 FP_COMP_OPS_EXE_SSE_FP_PACKED_DOUBLE +PMC1 FP_COMP_OPS_EXE_SSE_FP_SCALAR_DOUBLE +PMC2 SIMD_FP_256_PACKED_DOUBLE +MBOX0C0 CAS_COUNT_RD +MBOX0C1 CAS_COUNT_WR +MBOX1C0 CAS_COUNT_RD +MBOX1C1 CAS_COUNT_WR +MBOX2C0 CAS_COUNT_RD +MBOX2C1 CAS_COUNT_WR +MBOX3C0 CAS_COUNT_RD +MBOX3C1 CAS_COUNT_WR +MBOX4C0 CAS_COUNT_RD +MBOX4C1 CAS_COUNT_WR +MBOX5C0 CAS_COUNT_RD +MBOX5C1 CAS_COUNT_WR +MBOX6C0 CAS_COUNT_RD +MBOX6C1 CAS_COUNT_WR +MBOX7C0 CAS_COUNT_RD +MBOX7C1 CAS_COUNT_WR + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Energy [J] PWR0 +Power [W] PWR0/time +Energy DRAM [J] PWR3 +Power DRAM [W] PWR3/time +MFLOP/s 1.0E-06*(PMC0*2.0+PMC1+PMC2*4.0)/time +AVX [MFLOP/s] 1.0E-06*(PMC2*4.0)/time +Packed [MUOPS/s] 1.0E-06*(PMC0+PMC2)/time +Scalar [MUOPS/s] 1.0E-06*PMC1/time +Memory read bandwidth [MBytes/s] 1.0E-06*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX6C0+MBOX7C0)*64.0/time +Memory read data volume [GBytes] 1.0E-09*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX6C0+MBOX7C0)*64.0 +Memory write bandwidth [MBytes/s] 1.0E-06*(MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1+MBOX6C1+MBOX7C1)*64.0/time +Memory write data volume [GBytes] 1.0E-09*(MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1+MBOX6C1+MBOX7C1)*64.0 +Memory bandwidth [MBytes/s] 1.0E-06*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX6C0+MBOX7C0+MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1+MBOX6C1+MBOX7C1)*64.0/time +Memory data volume [GBytes] 1.0E-09*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX6C0+MBOX7C0+MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1+MBOX6C1+MBOX7C1)*64.0 +Operational intensity (PMC0*2.0+PMC1+PMC2*4.0)/((MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX6C0+MBOX7C0+MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1+MBOX6C1+MBOX7C1)*64.0) + +LONG +Formulas: +Power [W] = PWR_PKG_ENERGY/runtime +Power DRAM [W] = PWR_DRAM_ENERGY/runtime +MFLOP/s = 1.0E-06*(FP_COMP_OPS_EXE_SSE_FP_PACKED*2+FP_COMP_OPS_EXE_SSE_FP_SCALAR+SIMD_FP_256_PACKED_DOUBLE*4)/runtime +AVX [MFLOP/s] = 1.0E-06*(SIMD_FP_256_PACKED_DOUBLE*4)/runtime +Packed [MUOPS/s] = 1.0E-06*(FP_COMP_OPS_EXE_SSE_FP_PACKED_DOUBLE+SIMD_FP_256_PACKED_DOUBLE)/runtime +Scalar [MUOPS/s] = 1.0E-06*FP_COMP_OPS_EXE_SSE_FP_SCALAR_DOUBLE/runtime +Memory read bandwidth [MBytes/s] = 1.0E-06*(SUM(MBOXxC0))*64.0/time +Memory read data volume [GBytes] = 1.0E-09*(SUM(MBOXxC0))*64.0 +Memory write bandwidth [MBytes/s] = 1.0E-06*(SUM(MBOXxC1))*64.0/time +Memory write data volume [GBytes] = 1.0E-09*(SUM(MBOXxC1))*64.0 +Memory bandwidth [MBytes/s] = 1.0E-06*(SUM(MBOXxC0)+SUM(MBOXxC1))*64.0/time +Memory data volume [GBytes] = 1.0E-09*(SUM(MBOXxC0)+SUM(MBOXxC1))*64.0 +Operational intensity = (FP_COMP_OPS_EXE_SSE_FP_PACKED*2+FP_COMP_OPS_EXE_SSE_FP_SCALAR+SIMD_FP_256_PACKED_DOUBLE*4)/(SUM(MBOXxC0)+SUM(MBOXxC1))*64.0) +-- +Profiling group to measure memory bandwidth drawn by all cores of a socket. +Since this group is based on Uncore events it is only possible to measure on +a per socket base. Also outputs total data volume transferred from main memory. +SSE scalar and packed double precision FLOP rates. Also reports on packed AVX +32b instructions. Please note that the current FLOP measurements on SandyBridge +are potentially wrong. So you cannot trust these counters at the moment! +The operational intensity is calculated using the FP values of the cores and the +memory data volume of the whole socket. The actual operational intensity for +multiple CPUs can be found in the statistics table in the Sum column. + diff --git a/collectors/likwid/groups/ivybridgeEP/MEM_SP.txt b/collectors/likwid/groups/ivybridgeEP/MEM_SP.txt new file mode 100644 index 0000000..e541340 --- /dev/null +++ b/collectors/likwid/groups/ivybridgeEP/MEM_SP.txt @@ -0,0 +1,74 @@ +SHORT Power and Energy consumption + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PWR0 PWR_PKG_ENERGY +PWR3 PWR_DRAM_ENERGY +PMC0 FP_COMP_OPS_EXE_SSE_FP_PACKED_SINGLE +PMC1 FP_COMP_OPS_EXE_SSE_FP_SCALAR_SINGLE +PMC2 SIMD_FP_256_PACKED_SINGLE +MBOX0C0 CAS_COUNT_RD +MBOX0C1 CAS_COUNT_WR +MBOX1C0 CAS_COUNT_RD +MBOX1C1 CAS_COUNT_WR +MBOX2C0 CAS_COUNT_RD +MBOX2C1 CAS_COUNT_WR +MBOX3C0 CAS_COUNT_RD +MBOX3C1 CAS_COUNT_WR +MBOX4C0 CAS_COUNT_RD +MBOX4C1 CAS_COUNT_WR +MBOX5C0 CAS_COUNT_RD +MBOX5C1 CAS_COUNT_WR +MBOX6C0 CAS_COUNT_RD +MBOX6C1 CAS_COUNT_WR +MBOX7C0 CAS_COUNT_RD +MBOX7C1 CAS_COUNT_WR + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Energy [J] PWR0 +Power [W] PWR0/time +Energy DRAM [J] PWR3 +Power DRAM [W] PWR3/time +MFLOP/s 1.0E-06*(PMC0*4.0+PMC1+PMC2*8.0)/time +AVX [MFLOP/s] 1.0E-06*(PMC2*8.0)/time +Packed [MUOPS/s] 1.0E-06*(PMC0+PMC2)/time +Scalar [MUOPS/s] 1.0E-06*PMC1/time +Memory read bandwidth [MBytes/s] 1.0E-06*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX6C0+MBOX7C0)*64.0/time +Memory read data volume [GBytes] 1.0E-09*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX6C0+MBOX7C0)*64.0 +Memory write bandwidth [MBytes/s] 1.0E-06*(MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1+MBOX6C1+MBOX7C1)*64.0/time +Memory write data volume [GBytes] 1.0E-09*(MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1+MBOX6C1+MBOX7C1)*64.0 +Memory bandwidth [MBytes/s] 1.0E-06*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX6C0+MBOX7C0+MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1+MBOX6C1+MBOX7C1)*64.0/time +Memory data volume [GBytes] 1.0E-09*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX6C0+MBOX7C0+MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1+MBOX6C1+MBOX7C1)*64.0 +Operational intensity (PMC0*4.0+PMC1+PMC2*8.0)/((MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX6C0+MBOX7C0+MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1+MBOX6C1+MBOX7C1)*64.0) + +LONG +Formulas: +Power [W] = PWR_PKG_ENERGY/runtime +Power DRAM [W] = PWR_DRAM_ENERGY/runtime +MFLOP/s = 1.0E-06*(FP_COMP_OPS_EXE_SSE_FP_PACKED*4+FP_COMP_OPS_EXE_SSE_FP_SCALAR+SIMD_FP_256_PACKED_SINGLE*8)/runtime +AVX [MFLOP/s] = 1.0E-06*(SIMD_FP_256_PACKED_SINGLE*8)/runtime +Packed [MUOPS/s] = 1.0E-06*(FP_COMP_OPS_EXE_SSE_FP_PACKED_SINGLE+SIMD_FP_256_PACKED_SINGLE)/runtime +Scalar [MUOPS/s] = 1.0E-06*FP_COMP_OPS_EXE_SSE_FP_SCALAR_SINGLE/runtime +Memory read bandwidth [MBytes/s] = 1.0E-06*(SUM(MBOXxC0))*64.0/time +Memory read data volume [GBytes] = 1.0E-09*(SUM(MBOXxC0))*64.0 +Memory write bandwidth [MBytes/s] = 1.0E-06*(SUM(MBOXxC1))*64.0/time +Memory write data volume [GBytes] = 1.0E-09*(SUM(MBOXxC1))*64.0 +Memory bandwidth [MBytes/s] = 1.0E-06*(SUM(MBOXxC0)+SUM(MBOXxC1))*64.0/time +Memory data volume [GBytes] = 1.0E-09*(SUM(MBOXxC0)+SUM(MBOXxC1))*64.0 +Operational intensity = (FP_COMP_OPS_EXE_SSE_FP_PACKED*4+FP_COMP_OPS_EXE_SSE_FP_SCALAR+SIMD_FP_256_PACKED_SINGLE*8)/(SUM(MBOXxC0)+SUM(MBOXxC1))*64.0) +-- +Profiling group to measure memory bandwidth drawn by all cores of a socket. +Since this group is based on Uncore events it is only possible to measure on +a per socket base. Also outputs total data volume transferred from main memory. +SSE scalar and packed single precision FLOP rates. Also reports on packed AVX +32b instructions. Please note that the current FLOP measurements on IvyBridge +are potentially wrong. So you cannot trust these counters at the moment! +The operational intensity is calculated using the FP values of the cores and the +memory data volume of the whole socket. The actual operational intensity for +multiple CPUs can be found in the statistics table in the Sum column. diff --git a/collectors/likwid/groups/ivybridgeEP/NUMA.txt b/collectors/likwid/groups/ivybridgeEP/NUMA.txt new file mode 100644 index 0000000..41fbe62 --- /dev/null +++ b/collectors/likwid/groups/ivybridgeEP/NUMA.txt @@ -0,0 +1,33 @@ +SHORT Local and remote memory accesses + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 OFFCORE_RESPONSE_0_LOCAL_DRAM +PMC1 OFFCORE_RESPONSE_1_REMOTE_DRAM + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Local DRAM data volume [GByte] 1.E-09*PMC0*64 +Local DRAM bandwidth [MByte/s] 1.E-06*(PMC0*64)/time +Remote DRAM data volume [GByte] 1.E-09*PMC1*64 +Remote DRAM bandwidth [MByte/s] 1.E-06*(PMC1*64)/time +Memory data volume [GByte] 1.E-09*(PMC0+PMC1)*64 +Memory bandwidth [MByte/s] 1.E-06*((PMC0+PMC1)*64)/time + +LONG +Formulas: +CPI = CPU_CLK_UNHALTED_CORE/INSTR_RETIRED_ANY +Local DRAM data volume [GByte] = 1.E-09*OFFCORE_RESPONSE_0_LOCAL_DRAM*64 +Local DRAM bandwidth [MByte/s] = 1.E-06*(OFFCORE_RESPONSE_0_LOCAL_DRAM*64)/time +Remote DRAM data volume [GByte] = 1.E-09*OFFCORE_RESPONSE_1_REMOTE_DRAM*64 +Remote DRAM bandwidth [MByte/s] = 1.E-06*(OFFCORE_RESPONSE_1_REMOTE_DRAM*64)/time +Memory data volume [GByte] = 1.E-09*(OFFCORE_RESPONSE_0_LOCAL_DRAM+OFFCORE_RESPONSE_1_REMOTE_DRAM)*64 +Memory bandwidth [MByte/s] = 1.E-06*((OFFCORE_RESPONSE_0_LOCAL_DRAM+OFFCORE_RESPONSE_1_REMOTE_DRAM)*64)/time +-- +This performance group measures the data traffic of CPU cores to local and remote +memory. diff --git a/collectors/likwid/groups/ivybridgeEP/PORT_USAGE.txt b/collectors/likwid/groups/ivybridgeEP/PORT_USAGE.txt new file mode 100644 index 0000000..d509607 --- /dev/null +++ b/collectors/likwid/groups/ivybridgeEP/PORT_USAGE.txt @@ -0,0 +1,40 @@ +SHORT Execution port utilization + +REQUIRE_NOHT + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 UOPS_DISPATCHED_PORT_PORT_0 +PMC1 UOPS_DISPATCHED_PORT_PORT_1 +PMC2 UOPS_DISPATCHED_PORT_PORT_2 +PMC3 UOPS_DISPATCHED_PORT_PORT_3 +PMC4 UOPS_DISPATCHED_PORT_PORT_4 +PMC5 UOPS_DISPATCHED_PORT_PORT_5 + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Port0 usage ratio PMC0/(PMC0+PMC1+PMC2+PMC3+PMC4+PMC5) +Port1 usage ratio PMC1/(PMC0+PMC1+PMC2+PMC3+PMC4+PMC5) +Port2 usage ratio PMC2/(PMC0+PMC1+PMC2+PMC3+PMC4+PMC5) +Port3 usage ratio PMC3/(PMC0+PMC1+PMC2+PMC3+PMC4+PMC5) +Port4 usage ratio PMC4/(PMC0+PMC1+PMC2+PMC3+PMC4+PMC5) +Port5 usage ratio PMC5/(PMC0+PMC1+PMC2+PMC3+PMC4+PMC5) + +LONG +Formulas: +Port0 usage ratio = UOPS_DISPATCHED_PORT_PORT_0/SUM(UOPS_DISPATCHED_PORT_PORT_*) +Port1 usage ratio = UOPS_DISPATCHED_PORT_PORT_1/SUM(UOPS_DISPATCHED_PORT_PORT_*) +Port2 usage ratio = UOPS_DISPATCHED_PORT_PORT_2/SUM(UOPS_DISPATCHED_PORT_PORT_*) +Port3 usage ratio = UOPS_DISPATCHED_PORT_PORT_3/SUM(UOPS_DISPATCHED_PORT_PORT_*) +Port4 usage ratio = UOPS_DISPATCHED_PORT_PORT_4/SUM(UOPS_DISPATCHED_PORT_PORT_*) +Port5 usage ratio = UOPS_DISPATCHED_PORT_PORT_5/SUM(UOPS_DISPATCHED_PORT_PORT_*) +- +This group measures the execution port utilization in a CPU core. The group can +only be measured when HyperThreading is disabled because only then each CPU core +can program eight counters. diff --git a/collectors/likwid/groups/ivybridgeEP/QPI.txt b/collectors/likwid/groups/ivybridgeEP/QPI.txt new file mode 100644 index 0000000..a2f1339 --- /dev/null +++ b/collectors/likwid/groups/ivybridgeEP/QPI.txt @@ -0,0 +1,52 @@ +SHORT QPI Link Layer data + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +SBOX0C0 DIRECT2CORE_SUCCESS_RBT_HIT +SBOX1C0 DIRECT2CORE_SUCCESS_RBT_HIT +SBOX2C0 DIRECT2CORE_SUCCESS_RBT_HIT +SBOX0C1 TXL_FLITS_G0_DATA +SBOX1C1 TXL_FLITS_G0_DATA +SBOX2C1 TXL_FLITS_G0_DATA +SBOX0C2 TXL_FLITS_G0_NON_DATA +SBOX1C2 TXL_FLITS_G0_NON_DATA +SBOX2C2 TXL_FLITS_G0_NON_DATA +SBOX0C3 SBOX_CLOCKTICKS +SBOX1C3 SBOX_CLOCKTICKS +SBOX2C3 SBOX_CLOCKTICKS +SBOX0FIX QPI_RATE +SBOX1FIX QPI_RATE +SBOX2FIX QPI_RATE + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +QPI Speed Link 0 [GT/s] ((SBOX0C3)/time)*inverseClock*(8/1000) +QPI Speed Link 1 [GT/s] ((SBOX1C3)/time)*inverseClock*(8/1000) +QPI Speed Link 2 [GT/s] ((SBOX2C3)/time)*inverseClock*(8/1000) +QPI Rate Link 0 [GT/s] 1.E-09*SBOX0FIX +QPI Rate Link 1 [GT/s] 1.E-09*SBOX1FIX +QPI Rate Link 2 [GT/s] 1.E-09*SBOX2FIX +data from QPI to LLC [MByte] 1.E-06*(SBOX0C0+SBOX1C0+SBOX2C0)*8 +QPI data volume [MByte] 1.E-06*(SBOX0C1+SBOX1C1+SBOX2C1)*8 +QPI data bandwidth [MByte/s] 1.E-06*(SBOX0C1+SBOX1C1+SBOX2C1)*8/time +QPI link volume [MByte] 1.E-06*(SBOX0C1+SBOX1C1+SBOX2C1+SBOX0C2+SBOX1C2+SBOX2C2)*8 +QPI link bandwidth [MByte/s] 1.E-06*(SBOX0C1+SBOX1C1+SBOX2C1+SBOX0C2+SBOX1C2+SBOX2C2)*8/time + +LONG +Formulas: +QPI Speed Link 0/1/2 [GT/s] = ((SBOX_CLOCKTICKS)/time)*clock*(8/1000) +QPI Rate Link 0/1/2 [GT/s] = 1.E-09*(QPI_RATE) +data from QPI to LLC [MByte] = 1.E-06*(sum(DIRECT2CORE_SUCCESS_RBT_HIT)*64) +QPI data volume [MByte] = 1.E-06*(sum(TXL_FLITS_G0_DATA)*8) +QPI data bandwidth [MByte/s] = 1.E-06*(sum(TXL_FLITS_G0_DATA)*8)/runtime +QPI link volume [MByte] = 1.E-06*((sum(TXL_FLITS_G0_DATA)+sum(TXL_FLITS_G0_NON_DATA))*8) +QPI link bandwidth [MByte/s] = 1.E-06*((sum(TXL_FLITS_G0_DATA)+sum(TXL_FLITS_G0_NON_DATA))*8)/runtime +-- +The Intel QPI Link Layer is responsible for packetizing requests from the caching agent (CBOXes) +on the way out to the system interface. + diff --git a/collectors/likwid/groups/ivybridgeEP/RECOVERY.txt b/collectors/likwid/groups/ivybridgeEP/RECOVERY.txt new file mode 100644 index 0000000..7928ee4 --- /dev/null +++ b/collectors/likwid/groups/ivybridgeEP/RECOVERY.txt @@ -0,0 +1,22 @@ +SHORT Recovery duration + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 INT_MISC_RECOVERY_CYCLES +PMC1 INT_MISC_RECOVERY_COUNT + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Avg. recovery duration PMC0/PMC1 + +LONG +Formulas: +Avg. recovery duration = INT_MISC_RECOVERY_CYCLES/INT_MISC_RECOVERY_COUNT +- +This group measures the duration of recoveries after SSE exception, memory +disambiguation, etc... diff --git a/collectors/likwid/groups/ivybridgeEP/TLB_DATA.txt b/collectors/likwid/groups/ivybridgeEP/TLB_DATA.txt new file mode 100644 index 0000000..8d94e05 --- /dev/null +++ b/collectors/likwid/groups/ivybridgeEP/TLB_DATA.txt @@ -0,0 +1,35 @@ +SHORT L2 data TLB miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 DTLB_LOAD_MISSES_CAUSES_A_WALK +PMC1 DTLB_STORE_MISSES_CAUSES_A_WALK +PMC2 DTLB_LOAD_MISSES_WALK_DURATION +PMC3 DTLB_STORE_MISSES_WALK_DURATION + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L1 DTLB load misses PMC0 +L1 DTLB load miss rate PMC0/FIXC0 +L1 DTLB load miss duration [Cyc] PMC2/PMC0 +L1 DTLB store misses PMC1 +L1 DTLB store miss rate PMC1/FIXC0 +L1 DTLB store miss duration [Cyc] PMC3/PMC1 + +LONG +Formulas: +L1 DTLB load misses = DTLB_LOAD_MISSES_CAUSES_A_WALK +L1 DTLB load miss rate = DTLB_LOAD_MISSES_CAUSES_A_WALK / INSTR_RETIRED_ANY +L1 DTLB load miss duration [Cyc] = DTLB_LOAD_MISSES_WALK_DURATION / DTLB_LOAD_MISSES_CAUSES_A_WALK +L1 DTLB store misses = DTLB_STORE_MISSES_CAUSES_A_WALK +L1 DTLB store miss rate = DTLB_STORE_MISSES_CAUSES_A_WALK / INSTR_RETIRED_ANY +L1 DTLB store miss duration [Cyc] = DTLB_STORE_MISSES_WALK_DURATION / DTLB_STORE_MISSES_CAUSES_A_WALK +- +The DTLB load and store miss rates gives a measure how often a TLB miss occurred +per instruction. The duration measures the time in cycles how long a walk did take. + diff --git a/collectors/likwid/groups/ivybridgeEP/TLB_INSTR.txt b/collectors/likwid/groups/ivybridgeEP/TLB_INSTR.txt new file mode 100644 index 0000000..235d977 --- /dev/null +++ b/collectors/likwid/groups/ivybridgeEP/TLB_INSTR.txt @@ -0,0 +1,28 @@ +SHORT L1 Instruction TLB miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 ITLB_MISSES_CAUSES_A_WALK +PMC1 ITLB_MISSES_WALK_DURATION + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L1 ITLB misses PMC0 +L1 ITLB miss rate PMC0/FIXC0 +L1 ITLB miss duration [Cyc] PMC1/PMC0 + + +LONG +Formulas: +L1 ITLB misses = ITLB_MISSES_CAUSES_A_WALK +L1 ITLB miss rate = ITLB_MISSES_CAUSES_A_WALK / INSTR_RETIRED_ANY +L1 ITLB miss duration [Cyc] = ITLB_MISSES_WALK_DURATION / ITLB_MISSES_CAUSES_A_WALK +- +The ITLB miss rates gives a measure how often a TLB miss occurred +per instruction. The duration measures the time in cycles how long a walk did take. + diff --git a/collectors/likwid/groups/ivybridgeEP/TMA.txt b/collectors/likwid/groups/ivybridgeEP/TMA.txt new file mode 100644 index 0000000..afb4126 --- /dev/null +++ b/collectors/likwid/groups/ivybridgeEP/TMA.txt @@ -0,0 +1,48 @@ +SHORT Top down cycle allocation + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 UOPS_ISSUED_ANY +PMC1 UOPS_RETIRED_RETIRE_SLOTS +PMC2 IDQ_UOPS_NOT_DELIVERED_CORE +PMC3 INT_MISC_RECOVERY_CYCLES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +IPC FIXC0/FIXC1 +Total Slots 4*FIXC1 +Slots Retired PMC1 +Fetch Bubbles PMC2 +Recovery Bubbles 4*PMC3 +Front End [%] PMC2/(4*FIXC1)*100 +Speculation [%] (PMC0-PMC1+(4*PMC3))/(4*FIXC1)*100 +Retiring [%] PMC1/(4*FIXC1)*100 +Back End [%] (1-((PMC2+PMC0+(4*PMC3))/(4*FIXC1)))*100 + +LONG +Formulas: +Total Slots = 4*CPU_CLK_UNHALTED_CORE +Slots Retired = UOPS_RETIRED_RETIRE_SLOTS +Fetch Bubbles = IDQ_UOPS_NOT_DELIVERED_CORE +Recovery Bubbles = 4*INT_MISC_RECOVERY_CYCLES +Front End [%] = IDQ_UOPS_NOT_DELIVERED_CORE/(4*CPU_CLK_UNHALTED_CORE)*100 +Speculation [%] = (UOPS_ISSUED_ANY-UOPS_RETIRED_RETIRE_SLOTS+(4*INT_MISC_RECOVERY_CYCLES))/(4*CPU_CLK_UNHALTED_CORE)*100 +Retiring [%] = UOPS_RETIRED_RETIRE_SLOTS/(4*CPU_CLK_UNHALTED_CORE)*100 +Back End [%] = (1-((IDQ_UOPS_NOT_DELIVERED_CORE+UOPS_ISSUED_ANY+(4*INT_MISC_RECOVERY_CYCLES))/(4*CPU_CLK_UNHALTED_CORE)))*100 +-- +This performance group measures cycles to determine percentage of time spent in +front end, back end, retiring and speculation. These metrics are published and +verified by Intel. Further information: +Webpage describing Top-Down Method and its usage in Intel vTune: +https://software.intel.com/en-us/vtune-amplifier-help-tuning-applications-using-a-top-down-microarchitecture-analysis-method +Paper by Yasin Ahmad: +https://sites.google.com/site/analysismethods/yasin-pubs/TopDown-Yasin-ISPASS14.pdf?attredirects=0 +Slides by Yasin Ahmad: +http://www.cs.technion.ac.il/~erangi/TMA_using_Linux_perf__Ahmad_Yasin.pdf +The performance group was originally published here: +http://perf.mvermeulen.com/2018/04/14/top-down-performance-counter-analysis-part-1-likwid/ diff --git a/collectors/likwid/groups/ivybridgeEP/UNCORECLOCK.txt b/collectors/likwid/groups/ivybridgeEP/UNCORECLOCK.txt new file mode 100644 index 0000000..1cc1f98 --- /dev/null +++ b/collectors/likwid/groups/ivybridgeEP/UNCORECLOCK.txt @@ -0,0 +1,96 @@ +SHORT All Clocks + +EVENTSET +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +CBOX0C0 CBOX_CLOCKTICKS +CBOX1C0 CBOX_CLOCKTICKS +CBOX2C0 CBOX_CLOCKTICKS +CBOX3C0 CBOX_CLOCKTICKS +CBOX4C0 CBOX_CLOCKTICKS +CBOX5C0 CBOX_CLOCKTICKS +CBOX6C0 CBOX_CLOCKTICKS +CBOX7C0 CBOX_CLOCKTICKS +CBOX8C0 CBOX_CLOCKTICKS +CBOX9C0 CBOX_CLOCKTICKS +CBOX10C0 CBOX_CLOCKTICKS +CBOX11C0 CBOX_CLOCKTICKS +CBOX12C0 CBOX_CLOCKTICKS +CBOX13C0 CBOX_CLOCKTICKS +CBOX14C0 CBOX_CLOCKTICKS +MBOX0C0 DRAM_CLOCKTICKS +MBOX1C0 DRAM_CLOCKTICKS +MBOX2C0 DRAM_CLOCKTICKS +MBOX3C0 DRAM_CLOCKTICKS +MBOX0FIX DRAM_CLOCKTICKS +MBOX1FIX DRAM_CLOCKTICKS +MBOX2FIX DRAM_CLOCKTICKS +MBOX3FIX DRAM_CLOCKTICKS +SBOX0C0 SBOX_CLOCKTICKS +SBOX1C0 SBOX_CLOCKTICKS +SBOX2C0 SBOX_CLOCKTICKS +UBOXFIX UNCORE_CLOCK +BBOX0C0 BBOX_CLOCKTICKS +BBOX1C0 BBOX_CLOCKTICKS +WBOX0 WBOX_CLOCKTICKS +PBOX0 PBOX_CLOCKTICKS +RBOX0C0 RBOX_CLOCKTICKS +RBOX1C0 RBOX_CLOCKTICKS +RBOX2C0 RBOX_CLOCKTICKS +IBOX0C0 IBOX_CLOCKTICKS + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +UBOX Frequency [GHz] 1.E-09*UBOXFIX/(FIXC1*inverseClock) +CBOX0 Frequency [GHz] 1.E-09*CBOX0C0/(FIXC1*inverseClock) +CBOX1 Frequency [GHz] 1.E-09*CBOX1C0/(FIXC1*inverseClock) +CBOX2 Frequency [GHz] 1.E-09*CBOX2C0/(FIXC1*inverseClock) +CBOX3 Frequency [GHz] 1.E-09*CBOX3C0/(FIXC1*inverseClock) +CBOX4 Frequency [GHz] 1.E-09*CBOX4C0/(FIXC1*inverseClock) +CBOX5 Frequency [GHz] 1.E-09*CBOX5C0/(FIXC1*inverseClock) +CBOX6 Frequency [GHz] 1.E-09*CBOX6C0/(FIXC1*inverseClock) +CBOX7 Frequency [GHz] 1.E-09*CBOX7C0/(FIXC1*inverseClock) +CBOX8 Frequency [GHz] 1.E-09*CBOX8C0/(FIXC1*inverseClock) +CBOX9 Frequency [GHz] 1.E-09*CBOX9C0/(FIXC1*inverseClock) +CBOX10 Frequency [GHz] 1.E-09*CBOX10C0/(FIXC1*inverseClock) +CBOX11 Frequency [GHz] 1.E-09*CBOX11C0/(FIXC1*inverseClock) +CBOX12 Frequency [GHz] 1.E-09*CBOX12C0/(FIXC1*inverseClock) +CBOX13 Frequency [GHz] 1.E-09*CBOX13C0/(FIXC1*inverseClock) +CBOX14 Frequency [GHz] 1.E-09*CBOX14C0/(FIXC1*inverseClock) +MBOX0 Frequency [GHz] 1.E-09*MBOX0C0/(FIXC1*inverseClock) +MBOX0FIX Frequency [GHz] 1.E-09*MBOX0FIX/(FIXC1*inverseClock) +MBOX1 Frequency [GHz] 1.E-09*MBOX1C0/(FIXC1*inverseClock) +MBOX1FIX Frequency [GHz] 1.E-09*MBOX1FIX/(FIXC1*inverseClock) +MBOX2 Frequency [GHz] 1.E-09*MBOX2C0/(FIXC1*inverseClock) +MBOX2FIX Frequency [GHz] 1.E-09*MBOX2FIX/(FIXC1*inverseClock) +MBOX3 Frequency [GHz] 1.E-09*MBOX3C0/(FIXC1*inverseClock) +MBOX3FIX Frequency [GHz] 1.E-09*MBOX3FIX/(FIXC1*inverseClock) +SBOX0 Frequency [GHz] 1.E-09*SBOX0C0/(FIXC1*inverseClock) +SBOX1 Frequency [GHz] 1.E-09*SBOX1C0/(FIXC1*inverseClock) +SBOX2 Frequency [GHz] 1.E-09*SBOX2C0/(FIXC1*inverseClock) +BBOX0 Frequency [GHz] 1.E-09*BBOX0C0/(FIXC1*inverseClock) +BBOX1 Frequency [GHz] 1.E-09*BBOX1C0/(FIXC1*inverseClock) +WBOX Frequency [GHz] 1.E-09*WBOX0/(FIXC1*inverseClock) +PBOX Frequency [GHz] 1.E-09*PBOX0/(FIXC1*inverseClock) +RBOX0 Frequency [GHz] 1.E-09*RBOX0C0/(FIXC1*inverseClock) +RBOX1 Frequency [GHz] 1.E-09*RBOX1C0/(FIXC1*inverseClock) +RBOX2 Frequency [GHz] 1.E-09*RBOX2C0/(FIXC1*inverseClock) +IBOX Frequency [GHz] 1.E-09*IBOX0/(FIXC1*inverseClock) + + +LONG +Formulas: +UBOX Frequency [GHz] = 1.E-09*UNCORE_CLOCK/(CPU_CLK_UNHALTED_CORE*inverseClock) +CBOX[0-14] Frequency [GHz] = 1.E-09*CBOX_CLOCKTICKS/(CPU_CLK_UNHALTED_CORE*inverseClock) +MBOX[0-3] Frequency [GHz] = 1.E-09*DRAM_CLOCKTICKS/(CPU_CLK_UNHALTED_CORE*inverseClock) +MBOX[0-3]FIX Frequency [GHz] = 1.E-09*DRAM_CLOCKTICKS/(CPU_CLK_UNHALTED_CORE*inverseClock) +SBOX[0-2] Frequency [GHz] = 1.E-09*SBOX_CLOCKTICKS/(CPU_CLK_UNHALTED_CORE*inverseClock) +BBOX[0-1] Frequency [GHz] = 1.E-09*BBOX_CLOCKTICKS/(CPU_CLK_UNHALTED_CORE*inverseClock) +RBOX[0-2] Frequency [GHz] = 1.E-09*RBOX_CLOCKTICKS/(CPU_CLK_UNHALTED_CORE*inverseClock) +WBOX Frequency [GHz] = 1.E-09*WBOX_CLOCKTICKS/(CPU_CLK_UNHALTED_CORE*inverseClock) +PBOX Frequency [GHz] = 1.E-09*PBOX_CLOCKTICKS/(CPU_CLK_UNHALTED_CORE*inverseClock) +IBOX Frequency [GHz] = 1.E-09*IBOX_CLOCKTICKS/(CPU_CLK_UNHALTED_CORE*inverseClock) +-- +A Overview over the frequencies of all Uncore units. diff --git a/collectors/likwid/groups/ivybridgeEP/UOPS.txt b/collectors/likwid/groups/ivybridgeEP/UOPS.txt new file mode 100644 index 0000000..e6cc208 --- /dev/null +++ b/collectors/likwid/groups/ivybridgeEP/UOPS.txt @@ -0,0 +1,35 @@ +SHORT UOPs execution info + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 UOPS_ISSUED_ANY +PMC1 UOPS_EXECUTED_THREAD +PMC2 UOPS_RETIRED_ALL +PMC3 UOPS_ISSUED_FLAGS_MERGE + + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Issued UOPs PMC0 +Merged UOPs PMC3 +Executed UOPs PMC1 +Retired UOPs PMC2 + +LONG +Formulas: +Issued UOPs = UOPS_ISSUED_ANY +Merged UOPs = UOPS_ISSUED_FLAGS_MERGE +Executed UOPs = UOPS_EXECUTED_THREAD +Retired UOPs = UOPS_RETIRED_ALL +- +This group returns information about the instruction pipeline. It measures the +issued, executed and retired uOPs and returns the number of uOPs which were issued +but not executed as well as the number of uOPs which were executed but never retired. +The executed but not retired uOPs commonly come from speculatively executed branches. + diff --git a/collectors/likwid/groups/ivybridgeEP/UOPS_EXEC.txt b/collectors/likwid/groups/ivybridgeEP/UOPS_EXEC.txt new file mode 100644 index 0000000..7042df7 --- /dev/null +++ b/collectors/likwid/groups/ivybridgeEP/UOPS_EXEC.txt @@ -0,0 +1,31 @@ +SHORT UOPs execution + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 UOPS_EXECUTED_USED_CYCLES +PMC1 UOPS_EXECUTED_STALL_CYCLES +PMC2 CPU_CLOCK_UNHALTED_TOTAL_CYCLES +PMC3:EDGEDETECT UOPS_EXECUTED_STALL_CYCLES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Used cycles ratio [%] 100*PMC0/PMC2 +Unused cycles ratio [%] 100*PMC1/PMC2 +Avg stall duration [cycles] PMC1/PMC3:EDGEDETECT + + +LONG +Formulas: +Used cycles ratio [%] = 100*UOPS_EXECUTED_USED_CYCLES/CPU_CLK_UNHALTED_CORE +Unused cycles ratio [%] = 100*UOPS_EXECUTED_STALL_CYCLES/CPU_CLK_UNHALTED_CORE +Avg stall duration [cycles] = UOPS_EXECUTED_STALL_CYCLES/UOPS_EXECUTED_STALL_CYCLES:EDGEDETECT +- +This performance group returns the ratios of used and unused cycles regarding +the execution stage in the pipeline. Used cycles are all cycles where uOPs are +executed while unused cycles refer to pipeline stalls. Moreover, the group +calculates the average stall duration in cycles. diff --git a/collectors/likwid/groups/ivybridgeEP/UOPS_ISSUE.txt b/collectors/likwid/groups/ivybridgeEP/UOPS_ISSUE.txt new file mode 100644 index 0000000..9aac923 --- /dev/null +++ b/collectors/likwid/groups/ivybridgeEP/UOPS_ISSUE.txt @@ -0,0 +1,31 @@ +SHORT UOPs issueing + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 UOPS_ISSUED_USED_CYCLES +PMC1 UOPS_ISSUED_STALL_CYCLES +PMC2 CPU_CLOCK_UNHALTED_TOTAL_CYCLES +PMC3:EDGEDETECT UOPS_ISSUED_STALL_CYCLES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Used cycles ratio [%] 100*PMC0/PMC2 +Unused cycles ratio [%] 100*PMC1/PMC2 +Avg stall duration [cycles] PMC1/PMC3:EDGEDETECT + + +LONG +Formulas: +Used cycles ratio [%] = 100*UOPS_ISSUED_USED_CYCLES/CPU_CLK_UNHALTED_CORE +Unused cycles ratio [%] = 100*UOPS_ISSUED_STALL_CYCLES/CPU_CLK_UNHALTED_CORE +Avg stall duration [cycles] = UOPS_ISSUED_STALL_CYCLES/UOPS_ISSUED_STALL_CYCLES:EDGEDETECT +- +This performance group returns the ratios of used and unused cycles regarding +the issue stage in the pipeline. Used cycles are all cycles where uOPs are +issued while unused cycles refer to pipeline stalls. Moreover, the group +calculates the average stall duration in cycles. diff --git a/collectors/likwid/groups/ivybridgeEP/UOPS_RETIRE.txt b/collectors/likwid/groups/ivybridgeEP/UOPS_RETIRE.txt new file mode 100644 index 0000000..0f37585 --- /dev/null +++ b/collectors/likwid/groups/ivybridgeEP/UOPS_RETIRE.txt @@ -0,0 +1,31 @@ +SHORT UOPs retirement + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 UOPS_RETIRED_USED_CYCLES +PMC1 UOPS_RETIRED_STALL_CYCLES +PMC2 CPU_CLOCK_UNHALTED_TOTAL_CYCLES +PMC3:EDGEDETECT UOPS_RETIRED_STALL_CYCLES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Used cycles ratio [%] 100*PMC0/PMC2 +Unused cycles ratio [%] 100*PMC1/PMC2 +Avg stall duration [cycles] PMC1/PMC3:EDGEDETECT + + +LONG +Formulas: +Used cycles ratio [%] = 100*UOPS_RETIRED_USED_CYCLES/CPU_CLK_UNHALTED_CORE +Unused cycles ratio [%] = 100*UOPS_RETIRED_STALL_CYCLES/CPU_CLK_UNHALTED_CORE +Avg stall duration [cycles] = UOPS_RETIRED_STALL_CYCLES/UOPS_RETIRED_STALL_CYCLES:EDGEDETECT +- +This performance group returns the ratios of used and unused cycles regarding +the retirement stage in the pipeline (re-order buffer). Used cycles are all +cycles where uOPs are retired while unused cycles refer to pipeline stalls. +Moreover, the group calculates the average stall duration in cycles. diff --git a/collectors/likwid/groups/k10/BRANCH.txt b/collectors/likwid/groups/k10/BRANCH.txt new file mode 100644 index 0000000..5c4207e --- /dev/null +++ b/collectors/likwid/groups/k10/BRANCH.txt @@ -0,0 +1,26 @@ +SHORT Branch prediction miss rate/ratio + +EVENTSET +PMC0 INSTRUCTIONS_RETIRED +PMC1 BRANCH_RETIRED +PMC2 BRANCH_MISPREDICT_RETIRED + +METRICS +Runtime (RDTSC) [s] time +Branch rate PMC1/PMC0 +Branch misprediction rate PMC2/PMC0 +Branch misprediction ratio PMC2/PMC1 +Instructions per branch PMC0/PMC1 + +LONG +Formulas: +Branch rate = BRANCH_RETIRED/INSTRUCTIONS_RETIRED +Branch misprediction rate = BRANCH_MISPREDICT_RETIRED/INSTRUCTIONS_RETIRED +Branch misprediction ratio = BRANCH_MISPREDICT_RETIRED/BRANCH_RETIRED +Instructions per branch = INSTRUCTIONS_RETIRED/BRANCH_RETIRED +- +The rates state how often on average a branch or a mispredicted branch occurred +per instruction retired in total. The branch misprediction ratio sets directly +into relation what ration of all branch instruction where mispredicted. +Instructions per branch is 1/branch rate. + diff --git a/collectors/likwid/groups/k10/CACHE.txt b/collectors/likwid/groups/k10/CACHE.txt new file mode 100644 index 0000000..26d799f --- /dev/null +++ b/collectors/likwid/groups/k10/CACHE.txt @@ -0,0 +1,34 @@ +SHORT Data cache miss rate/ratio + +EVENTSET +PMC0 INSTRUCTIONS_RETIRED +PMC1 DATA_CACHE_ACCESSES +PMC2 DATA_CACHE_REFILLS_L2_ALL +PMC3 DATA_CACHE_REFILLS_NORTHBRIDGE_ALL + +METRICS +Runtime (RDTSC) [s] time +data cache misses PMC2+PMC3 +data cache request rate PMC1/PMC0 +data cache miss rate (PMC2+PMC3)/PMC0 +data cache miss ratio (PMC2+PMC3)/PMC1 + +LONG +Formulas: +data cache misses = DATA_CACHE_REFILLS_L2_AL + DATA_CACHE_REFILLS_NORTHBRIDGE_ALL +data cache request rate = DATA_CACHE_ACCESSES / INSTRUCTIONS_RETIRED +data cache miss rate = (DATA_CACHE_REFILLS_L2_AL + DATA_CACHE_REFILLS_NORTHBRIDGE_ALL)/INSTRUCTIONS_RETIRED +data cache miss ratio = (DATA_CACHE_REFILLS_L2_AL + DATA_CACHE_REFILLS_NORTHBRIDGE_ALL)/DATA_CACHE_ACCESSES +- +This group measures the locality of your data accesses with regard to the +L1 cache. Data cache request rate tells you how data intensive your code is +or how many data accesses you have on average per instruction. +The data cache miss rate gives a measure how often it was necessary to get +cache lines from higher levels of the memory hierarchy. And finally +data cache miss ratio tells you how many of your memory references required +a cache line to be loaded from a higher level. While the# data cache miss rate +might be given by your algorithm you should try to get data cache miss ratio +as low as possible by increasing your cache reuse. +This group was taken from the whitepaper -Basic Performance Measurements for AMD Athlon 64, +AMD Opteron and AMD Phenom Processors- from Paul J. Drongowski. + diff --git a/collectors/likwid/groups/k10/CPI.txt b/collectors/likwid/groups/k10/CPI.txt new file mode 100644 index 0000000..850afed --- /dev/null +++ b/collectors/likwid/groups/k10/CPI.txt @@ -0,0 +1,26 @@ +SHORT Cycles per instruction + +EVENTSET +PMC0 INSTRUCTIONS_RETIRED +PMC1 CPU_CLOCKS_UNHALTED +PMC2 UOPS_RETIRED + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] PMC1*inverseClock +CPI PMC1/PMC0 +CPI (based on uops) PMC1/PMC2 +IPC PMC0/PMC1 + +LONG +Formulas: +CPI = CPU_CLOCKS_UNHALTED/RETIRED_INSTRUCTIONS +CPI (based on uops) = CPU_CLOCKS_UNHALTED/RETIRED_UOPS +IPC = RETIRED_INSTRUCTIONS/CPU_CLOCKS_UNHALTED +- +This group measures how efficient the processor works with +regard to instruction throughput. Also important as a standalone +metric is INSTRUCTIONS_RETIRED as it tells you how many instruction +you need to execute for a task. An optimization might show very +low CPI values but execute many more instruction for it. + diff --git a/collectors/likwid/groups/k10/FLOPS_DP.txt b/collectors/likwid/groups/k10/FLOPS_DP.txt new file mode 100644 index 0000000..89f0ac2 --- /dev/null +++ b/collectors/likwid/groups/k10/FLOPS_DP.txt @@ -0,0 +1,24 @@ +SHORT Double Precision MFLOP/s + +EVENTSET +PMC0 SSE_RETIRED_ADD_DOUBLE_FLOPS +PMC1 SSE_RETIRED_MULT_DOUBLE_FLOPS +PMC2 CPU_CLOCKS_UNHALTED + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] PMC2*inverseClock +DP [MFLOP/s] 1.0E-06*(PMC0+PMC1)/time +DP Add [MFLOP/s] 1.0E-06*PMC0/time +DP Mult [MFLOP/s] 1.0E-06*PMC1/time + +LONG +Formulas: +DP [MFLOP/s] = 1.0E-06*(SSE_RETIRED_ADD_DOUBLE_FLOPS+SSE_RETIRED_MULT_DOUBLE_FLOPS)/time +DP Add [MFLOP/s] = 1.0E-06*(SSE_RETIRED_ADD_DOUBLE_FLOPS)/time +DP Mult [MFLOP/s] = 1.0E-06*(SSE_RETIRED_MULT_DOUBLE_FLOPS)/time +- +Profiling group to measure double SSE FLOPs. +Don't forget that your code might also execute X87 FLOPs. + + diff --git a/collectors/likwid/groups/k10/FLOPS_SP.txt b/collectors/likwid/groups/k10/FLOPS_SP.txt new file mode 100644 index 0000000..590d39a --- /dev/null +++ b/collectors/likwid/groups/k10/FLOPS_SP.txt @@ -0,0 +1,24 @@ +SHORT Single Precision MFLOP/s + +EVENTSET +PMC0 SSE_RETIRED_ADD_SINGLE_FLOPS +PMC1 SSE_RETIRED_MULT_SINGLE_FLOPS +PMC2 CPU_CLOCKS_UNHALTED + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] PMC2*inverseClock +SP [MFLOP/s] 1.0E-06*(PMC0+PMC1)/time +SP Add [MFLOP/s] 1.0E-06*PMC0/time +SP Mult [MFLOP/s] 1.0E-06*PMC1/time + +LONG +Formulas: +SP [MFLOP/s] = 1.0E-06*(SSE_RETIRED_ADD_SINGLE_FLOPS+SSE_RETIRED_MULT_SINGLE_FLOPS)/time +SP Add [MFLOP/s] = 1.0E-06*(SSE_RETIRED_ADD_SINGLE_FLOPS)/time +SP Mult [MFLOP/s] = 1.0E-06*(SSE_RETIRED_MULT_SINGLE_FLOPS)/time +- +Profiling group to measure single precision SSE FLOPs. +Don't forget that your code might also execute X87 FLOPs. + + diff --git a/collectors/likwid/groups/k10/FLOPS_X87.txt b/collectors/likwid/groups/k10/FLOPS_X87.txt new file mode 100644 index 0000000..62fbefc --- /dev/null +++ b/collectors/likwid/groups/k10/FLOPS_X87.txt @@ -0,0 +1,25 @@ +SHORT X87 MFLOP/s + +EVENTSET +PMC0 X87_FLOPS_RETIRED_ADD +PMC1 X87_FLOPS_RETIRED_MULT +PMC2 X87_FLOPS_RETIRED_DIV +PMC3 CPU_CLOCKS_UNHALTED + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] PMC3*inverseClock +X87 [MFLOP/s] 1.0E-06*(PMC0+PMC1+PMC2)/time +X87 Add [MFLOP/s] 1.0E-06*PMC0/time +X87 Mult [MFLOP/s] 1.0E-06*PMC1/time +X87 Div [MFLOP/s] 1.0E-06*PMC2/time + +LONG +Formulas: +X87 [MFLOP/s] = 1.0E-06*(X87_FLOPS_RETIRED_ADD+X87_FLOPS_RETIRED_MULT+X87_FLOPS_RETIRED_DIV)/time +X87 Add [MFLOP/s] = 1.0E-06*X87_FLOPS_RETIRED_ADD/time +X87 Mult [MFLOP/s] = 1.0E-06*X87_FLOPS_RETIRED_MULT/time +X87 Div [MFLOP/s] = 1.0E-06*X87_FLOPS_RETIRED_DIV/time +- +Profiling group to measure X87 FLOP rates. + diff --git a/collectors/likwid/groups/k10/FPU_EXCEPTION.txt b/collectors/likwid/groups/k10/FPU_EXCEPTION.txt new file mode 100644 index 0000000..23d3c54 --- /dev/null +++ b/collectors/likwid/groups/k10/FPU_EXCEPTION.txt @@ -0,0 +1,21 @@ +SHORT Floating point exceptions + +EVENTSET +PMC0 INSTRUCTIONS_RETIRED +PMC1 FP_INSTRUCTIONS_RETIRED_ALL +PMC2 FPU_EXCEPTIONS_ALL + +METRICS +Runtime (RDTSC) [s] time +Overall FP exception rate PMC2/PMC0 +FP exception rate PMC2/PMC1 + +LONG +Formulas: +Overall FP exception rate = FPU_EXCEPTIONS_ALL / INSTRUCTIONS_RETIRED +FP exception rate = FPU_EXCEPTIONS_ALL / FP_INSTRUCTIONS_RETIRED_ALL +- +Floating point exceptions occur e.g. on the treatment of denormal numbers. +There might be a large penalty if there are too many floating point +exceptions. + diff --git a/collectors/likwid/groups/k10/ICACHE.txt b/collectors/likwid/groups/k10/ICACHE.txt new file mode 100644 index 0000000..5150496 --- /dev/null +++ b/collectors/likwid/groups/k10/ICACHE.txt @@ -0,0 +1,23 @@ +SHORT Instruction cache miss rate/ratio + +EVENTSET +PMC0 INSTRUCTIONS_RETIRED +PMC1 ICACHE_FETCHES +PMC2 ICACHE_REFILLS_L2 +PMC3 ICACHE_REFILLS_MEM + +METRICS +Runtime (RDTSC) [s] time +L1I request rate PMC1/PMC0 +L1I miss rate (PMC2+PMC3)/PMC0 +L1I miss ratio (PMC2+PMC3)/PMC1 + +LONG +Formulas: +L1I request rate = ICACHE_FETCHES / INSTRUCTIONS_RETIRED +L1I miss rate = (ICACHE_REFILLS_L2+ICACHE_REFILLS_MEM)/INSTRUCTIONS_RETIRED +L1I miss ratio = (ICACHE_REFILLS_L2+ICACHE_REFILLS_MEM)/ICACHE_FETCHES +- +This group measures the locality of your instruction code with regard to the +L1 I-Cache. + diff --git a/collectors/likwid/groups/k10/L2.txt b/collectors/likwid/groups/k10/L2.txt new file mode 100644 index 0000000..fae6fb0 --- /dev/null +++ b/collectors/likwid/groups/k10/L2.txt @@ -0,0 +1,33 @@ +SHORT L2 cache bandwidth in MBytes/s + +EVENTSET +PMC0 DATA_CACHE_REFILLS_L2_ALL +PMC1 DATA_CACHE_EVICTED_ALL +PMC2 CPU_CLOCKS_UNHALTED + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] PMC2*inverseClock +L2D load bandwidth [MBytes/s] 1.0E-06*PMC0*64.0/time +L2D load data volume [GBytes] 1.0E-09*PMC0*64.0 +L2D evict bandwidth [MBytes/s] 1.0E-06*PMC1*64.0/time +L2D evict data volume [GBytes] 1.0E-09*PMC1*64.0 +L2 bandwidth [MBytes/s] 1.0E-06*(PMC0+PMC1)*64.0/time +L2 data volume [GBytes] 1.0E-09*(PMC0+PMC1)*64.0 + +LONG +Formulas: +L2D load bandwidth [MBytes/s] = 1.0E-06*DATA_CACHE_REFILLS_L2_ALL*64.0/time +L2D load data volume [GBytes] = 1.0E-09*DATA_CACHE_REFILLS_L2_ALL*64.0 +L2D evict bandwidth [MBytes/s] = 1.0E-06*DATA_CACHE_EVICTED_ALL*64.0/time +L2D evict data volume [GBytes] = 1.0E-09*DATA_CACHE_EVICTED_ALL*64.0 +L2 bandwidth [MBytes/s] = 1.0E-06*(DATA_CACHE_REFILLS_L2_ALL+DATA_CACHE_EVICTED_ALL)*64/time +L2 data volume [GBytes] = 1.0E-09*(DATA_CACHE_REFILLS_L2_ALL+DATA_CACHE_EVICTED_ALL)*64 +- +Profiling group to measure L2 cache bandwidth. The bandwidth is +computed by the number of cache line loaded from L2 to L1 and the +number of modified cache lines evicted from the L1. +Note that this bandwidth also includes data transfers due to a +write allocate load on a store miss in L1 and copy back transfers if +originated from L2. + diff --git a/collectors/likwid/groups/k10/L2CACHE.txt b/collectors/likwid/groups/k10/L2CACHE.txt new file mode 100644 index 0000000..2d29e43 --- /dev/null +++ b/collectors/likwid/groups/k10/L2CACHE.txt @@ -0,0 +1,32 @@ +SHORT L2 cache miss rate/ratio + +EVENTSET +PMC0 INSTRUCTIONS_RETIRED +PMC1 L2_REQUESTS_ALL +PMC2 L2_MISSES_ALL +PMC3 L2_FILL_ALL + +METRICS +Runtime (RDTSC) [s] time +L2 request rate (PMC1+PMC3)/PMC0 +L2 miss rate PMC2/PMC0 +L2 miss ratio PMC2/(PMC1+PMC3) + +LONG +Formulas: +L2 request rate = (L2_REQUESTS_ALL+L2_FILL_ALL)/INSTRUCTIONS_RETIRED +L2 miss rate = L2_MISSES_ALL/INSTRUCTIONS_RETIRED +L2 miss ratio = L2_MISSES_ALL/(L2_REQUESTS_ALL+L2_FILL_ALL) +- +This group measures the locality of your data accesses with regard to the +L2 cache. L2 request rate tells you how data intensive your code is +or how many data accesses you have on average per instruction. +The L2 miss rate gives a measure how often it was necessary to get +cache lines from memory. And finally L2 miss ratio tells you how many of your +memory references required a cache line to be loaded from a higher level. +While the# data cache miss rate might be given by your algorithm you should +try to get data cache miss ratio as low as possible by increasing your cache reuse. +This group was taken from the whitepaper -Basic Performance Measurements for AMD Athlon 64, +AMD Opteron and AMD Phenom Processors- from Paul J. Drongowski. + + diff --git a/collectors/likwid/groups/k10/MEM.txt b/collectors/likwid/groups/k10/MEM.txt new file mode 100644 index 0000000..f9f5a91 --- /dev/null +++ b/collectors/likwid/groups/k10/MEM.txt @@ -0,0 +1,35 @@ +SHORT Main memory bandwidth in MBytes/s + +EVENTSET +PMC0 NORTHBRIDGE_READ_RESPONSE_ALL +PMC1 OCTWORDS_WRITE_TRANSFERS +PMC2 DRAM_ACCESSES_DCTO_ALL +PMC3 DRAM_ACCESSES_DCT1_ALL + +METRICS +Runtime (RDTSC) [s] time +Memory read bandwidth [MBytes/s] 1.0E-06*PMC0*64.0/time +Memory read data volume [GBytes] 1.0E-09*PMC0*64.0 +Memory write bandwidth [MBytes/s] 1.0E-06*PMC1*8.0/time +Memory write data volume [GBytes] 1.0E-09*PMC1*8.0 +Memory bandwidth [MBytes/s] 1.0E-06*(PMC2+PMC3)*64.0/time +Memory data volume [GBytes] 1.0E-09*(PMC2+PMC3)*64.0 + +LONG +Formulas: +Memory read bandwidth [MBytes/s] = 1.0E-06*NORTHBRIDGE_READ_RESPONSE_ALL*64/time +Memory read data volume [GBytes] = 1.0E-09*NORTHBRIDGE_READ_RESPONSE_ALL*64 +Memory write bandwidth [MBytes/s] = 1.0E-06*OCTWORDS_WRITE_TRANSFERS*8/time +Memory write data volume [GBytes] = 1.0E-09*OCTWORDS_WRITE_TRANSFERS*8 +Memory bandwidth [MBytes/s] = 1.0E-06*(DRAM_ACCESSES_DCTO_ALL+DRAM_ACCESSES_DCT1_ALL)*64/time +Memory data volume [GBytes] = 1.0E-09*(DRAM_ACCESSES_DCTO_ALL+DRAM_ACCESSES_DCT1_ALL)*64 +- +Profiling group to measure memory bandwidth drawn by all cores of a socket. +Note: As this group measures the accesses from all cores it only makes sense +to measure with one core per socket, similar as with the Intel Nehalem Uncore events. +The memory read bandwidth contains all data from DRAM, L3, or another cache, +including another core on the same node. The event OCTWORDS_WRITE_TRANSFERS counts +16 Byte transfers, not 64 Byte. + + + diff --git a/collectors/likwid/groups/k10/NUMA_0_3.txt b/collectors/likwid/groups/k10/NUMA_0_3.txt new file mode 100644 index 0000000..66e56d9 --- /dev/null +++ b/collectors/likwid/groups/k10/NUMA_0_3.txt @@ -0,0 +1,27 @@ +SHORT Bandwidth on the Hypertransport links + +EVENTSET +PMC0 CPU_TO_DRAM_LOCAL_TO_0 +PMC1 CPU_TO_DRAM_LOCAL_TO_1 +PMC2 CPU_TO_DRAM_LOCAL_TO_2 +PMC3 CPU_TO_DRAM_LOCAL_TO_3 + +METRICS +Runtime (RDTSC) [s] time +Hyper Transport link0 bandwidth [MBytes/s] 1.0E-06*PMC0*4.0/time +Hyper Transport link1 bandwidth [MBytes/s] 1.0E-06*PMC1*4.0/time +Hyper Transport link2 bandwidth [MBytes/s] 1.0E-06*PMC2*4.0/time +Hyper Transport link3 bandwidth [MBytes/s] 1.0E-06*PMC3*4.0/time + +LONG +Formulas: +Hyper Transport link0 bandwidth [MBytes/s] = 1.0E-06*CPU_TO_DRAM_LOCAL_TO_0*4.0/time +Hyper Transport link1 bandwidth [MBytes/s] = 1.0E-06*CPU_TO_DRAM_LOCAL_TO_1*4.0/time +Hyper Transport link2 bandwidth [MBytes/s] = 1.0E-06*CPU_TO_DRAM_LOCAL_TO_2*4.0/time +Hyper Transport link3 bandwidth [MBytes/s] = 1.0E-06*CPU_TO_DRAM_LOCAL_TO_3*4.0/time +- +Profiling group to measure the bandwidth over the Hypertransport links. Can be used +to detect NUMA problems. Usually there should be only limited traffic over the QPI +links for optimal performance. + + diff --git a/collectors/likwid/groups/k10/NUMA_4_7.txt b/collectors/likwid/groups/k10/NUMA_4_7.txt new file mode 100644 index 0000000..e13f2b9 --- /dev/null +++ b/collectors/likwid/groups/k10/NUMA_4_7.txt @@ -0,0 +1,27 @@ +SHORT Bandwidth on the Hypertransport links + +EVENTSET +PMC0 CPU_TO_DRAM_LOCAL_TO_4 +PMC1 CPU_TO_DRAM_LOCAL_TO_5 +PMC2 CPU_TO_DRAM_LOCAL_TO_6 +PMC3 CPU_TO_DRAM_LOCAL_TO_7 + +METRICS +Runtime (RDTSC) [s] time +Hyper Transport link4 bandwidth [MBytes/s] 1.0E-06*PMC0*4.0/time +Hyper Transport link5 bandwidth [MBytes/s] 1.0E-06*PMC1*4.0/time +Hyper Transport link6 bandwidth [MBytes/s] 1.0E-06*PMC2*4.0/time +Hyper Transport link7 bandwidth [MBytes/s] 1.0E-06*PMC3*4.0/time + +LONG +Formulas: +Hyper Transport link4 bandwidth [MBytes/s] = 1.0E-06*CPU_TO_DRAM_LOCAL_TO_0*4.0/time +Hyper Transport link5 bandwidth [MBytes/s] = 1.0E-06*CPU_TO_DRAM_LOCAL_TO_1*4.0/time +Hyper Transport link6 bandwidth [MBytes/s] = 1.0E-06*CPU_TO_DRAM_LOCAL_TO_2*4.0/time +Hyper Transport link7 bandwidth [MBytes/s] = 1.0E-06*CPU_TO_DRAM_LOCAL_TO_3*4.0/time +- +Profiling group to measure the bandwidth over the Hypertransport links. Can be used +to detect NUMA problems. Usually there should be only limited traffic over the QPI +links for optimal performance. + + diff --git a/collectors/likwid/groups/k10/TLB.txt b/collectors/likwid/groups/k10/TLB.txt new file mode 100644 index 0000000..25cab33 --- /dev/null +++ b/collectors/likwid/groups/k10/TLB.txt @@ -0,0 +1,35 @@ +SHORT TLB miss rate/ratio + +EVENTSET +PMC0 INSTRUCTIONS_RETIRED +PMC1 DATA_CACHE_ACCESSES +PMC2 DTLB_L2_HIT_ALL +PMC3 DTLB_L2_MISS_ALL + +METRICS +Runtime (RDTSC) [s] time +L1 DTLB request rate PMC1/PMC0 +L1 DTLB miss rate (PMC2+PMC3)/PMC0 +L1 DTLB miss ratio (PMC2+PMC3)/PMC1 +L2 DTLB request rate (PMC2+PMC3)/PMC0 +L2 DTLB miss rate PMC3/PMC0 +L2 DTLB miss ratio PMC3/(PMC2+PMC3) + + +LONG +Formulas: +L1 DTLB request rate = DATA_CACHE_ACCESSES / INSTRUCTIONS_RETIRED +L1 DTLB miss rate = (DTLB_L2_HIT_ALL+DTLB_L2_MISS_ALL)/INSTRUCTIONS_RETIRED +L1 DTLB miss ratio = (DTLB_L2_HIT_ALL+DTLB_L2_MISS_ALL)/DATA_CACHE_ACCESSES +L2 DTLB request rate = (DTLB_L2_HIT_ALL+DTLB_L2_MISS_ALL)/INSTRUCTIONS_RETIRED +L2 DTLB miss rate = DTLB_L2_MISS_ALL / INSTRUCTIONS_RETIRED +L2 DTLB miss ratio = DTLB_L2_MISS_ALL / (DTLB_L2_HIT_ALL+DTLB_L2_MISS_ALL) +- +L1 DTLB request rate tells you how data intensive your code is +or how many data accesses you have on average per instruction. +The DTLB miss rate gives a measure how often a TLB miss occurred +per instruction. And finally L1 DTLB miss ratio tells you how many +of your memory references required caused a TLB miss on average. +NOTE: The L2 metrics are only relevant if L2 DTLB request rate is equal to the L1 DTLB miss rate! +This group was taken from the whitepaper Basic -Performance Measurements for AMD Athlon 64, +AMD Opteron and AMD Phenom Processors- from Paul J. Drongowski. diff --git a/collectors/likwid/groups/k8/BRANCH.txt b/collectors/likwid/groups/k8/BRANCH.txt new file mode 100644 index 0000000..f465335 --- /dev/null +++ b/collectors/likwid/groups/k8/BRANCH.txt @@ -0,0 +1,25 @@ +SHORT Branch prediction miss rate/ratio + +EVENTSET +PMC0 INSTRUCTIONS_RETIRED +PMC1 BRANCH_RETIRED +PMC2 BRANCH_MISPREDICT_RETIRED + +METRICS +Runtime (RDTSC) [s] time +Branch rate PMC1/PMC0 +Branch misprediction rate PMC2/PMC0 +Branch misprediction ratio PMC2/PMC1 +Instructions per branch PMC0/PMC1 + +LONG +Formulas: +Branch rate = BRANCH_RETIRED/INSTRUCTIONS_RETIRED +Branch misprediction rate = BRANCH_MISPREDICT_RETIRED/INSTRUCTIONS_RETIRED +Branch misprediction ratio = BRANCH_MISPREDICT_RETIRED/BRANCH_RETIRED +Instructions per branch = INSTRUCTIONS_RETIRED/BRANCH_RETIRED +- +The rates state how often on average a branch or a mispredicted branch occurred +per instruction retired in total. The branch misprediction ratio sets directly +into relation what ration of all branch instruction where mispredicted. +Instructions per branch is 1/branch rate. diff --git a/collectors/likwid/groups/k8/CACHE.txt b/collectors/likwid/groups/k8/CACHE.txt new file mode 100644 index 0000000..e5e813e --- /dev/null +++ b/collectors/likwid/groups/k8/CACHE.txt @@ -0,0 +1,33 @@ +SHORT Data cache miss rate/ratio + +EVENTSET +PMC0 INSTRUCTIONS_RETIRED +PMC1 DATA_CACHE_ACCESSES +PMC2 DATA_CACHE_REFILLS_L2_ALL +PMC3 DATA_CACHE_REFILLS_NORTHBRIDGE_ALL + +METRICS +Runtime (RDTSC) [s] time +data cache misses PMC2+PMC3 +data cache request rate PMC1/PMC0 +data cache miss rate (PMC2+PMC3)/PMC0 +data cache miss ratio (PMC2+PMC3)/PMC1 + +LONG +Formulas: +data cache misses = DATA_CACHE_REFILLS_L2_AL + DATA_CACHE_REFILLS_NORTHBRIDGE_ALL +data cache request rate = DATA_CACHE_ACCESSES / INSTRUCTIONS_RETIRED +data cache miss rate = (DATA_CACHE_REFILLS_L2_AL + DATA_CACHE_REFILLS_NORTHBRIDGE_ALL)/INSTRUCTIONS_RETIRED +data cache miss ratio = (DATA_CACHE_REFILLS_L2_AL + DATA_CACHE_REFILLS_NORTHBRIDGE_ALL)/DATA_CACHE_ACCESSES +- +This group measures the locality of your data accesses with regard to the +L1 cache. Data cache request rate tells you how data intensive your code is +or how many data accesses you have on average per instruction. +The data cache miss rate gives a measure how often it was necessary to get +cache lines from higher levels of the memory hierarchy. And finally +data cache miss ratio tells you how many of your memory references required +a cache line to be loaded from a higher level. While the# data cache miss rate +might be given by your algorithm you should try to get data cache miss ratio +as low as possible by increasing your cache reuse. +This group was taken from the whitepaper -Basic Performance Measurements for AMD Athlon 64, +AMD Opteron and AMD Phenom Processors- from Paul J. Drongowski. diff --git a/collectors/likwid/groups/k8/CPI.txt b/collectors/likwid/groups/k8/CPI.txt new file mode 100644 index 0000000..850afed --- /dev/null +++ b/collectors/likwid/groups/k8/CPI.txt @@ -0,0 +1,26 @@ +SHORT Cycles per instruction + +EVENTSET +PMC0 INSTRUCTIONS_RETIRED +PMC1 CPU_CLOCKS_UNHALTED +PMC2 UOPS_RETIRED + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] PMC1*inverseClock +CPI PMC1/PMC0 +CPI (based on uops) PMC1/PMC2 +IPC PMC0/PMC1 + +LONG +Formulas: +CPI = CPU_CLOCKS_UNHALTED/RETIRED_INSTRUCTIONS +CPI (based on uops) = CPU_CLOCKS_UNHALTED/RETIRED_UOPS +IPC = RETIRED_INSTRUCTIONS/CPU_CLOCKS_UNHALTED +- +This group measures how efficient the processor works with +regard to instruction throughput. Also important as a standalone +metric is INSTRUCTIONS_RETIRED as it tells you how many instruction +you need to execute for a task. An optimization might show very +low CPI values but execute many more instruction for it. + diff --git a/collectors/likwid/groups/k8/ICACHE.txt b/collectors/likwid/groups/k8/ICACHE.txt new file mode 100644 index 0000000..5150496 --- /dev/null +++ b/collectors/likwid/groups/k8/ICACHE.txt @@ -0,0 +1,23 @@ +SHORT Instruction cache miss rate/ratio + +EVENTSET +PMC0 INSTRUCTIONS_RETIRED +PMC1 ICACHE_FETCHES +PMC2 ICACHE_REFILLS_L2 +PMC3 ICACHE_REFILLS_MEM + +METRICS +Runtime (RDTSC) [s] time +L1I request rate PMC1/PMC0 +L1I miss rate (PMC2+PMC3)/PMC0 +L1I miss ratio (PMC2+PMC3)/PMC1 + +LONG +Formulas: +L1I request rate = ICACHE_FETCHES / INSTRUCTIONS_RETIRED +L1I miss rate = (ICACHE_REFILLS_L2+ICACHE_REFILLS_MEM)/INSTRUCTIONS_RETIRED +L1I miss ratio = (ICACHE_REFILLS_L2+ICACHE_REFILLS_MEM)/ICACHE_FETCHES +- +This group measures the locality of your instruction code with regard to the +L1 I-Cache. + diff --git a/collectors/likwid/groups/k8/L2.txt b/collectors/likwid/groups/k8/L2.txt new file mode 100644 index 0000000..63b9b7f --- /dev/null +++ b/collectors/likwid/groups/k8/L2.txt @@ -0,0 +1,31 @@ +SHORT L2 cache bandwidth in MBytes/s + +EVENTSET +PMC0 DATA_CACHE_REFILLS_L2_ALL +PMC1 DATA_CACHE_EVICTED_ALL +PMC2 CPU_CLOCKS_UNHALTED + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] PMC2*inverseClock +L2 bandwidth [MBytes/s] 1.0E-06*(PMC0+PMC1)*64.0/time +L2 data volume [GBytes] 1.0E-09*(PMC0+PMC1)*64.0 +L2 refill bandwidth [MBytes/s] 1.0E-06*PMC0*64.0/time +L2 evict [MBytes/s] 1.0E-06*PMC1*64.0/time + +LONG +Formulas: +L2 bandwidth [MBytes/s] = 1.0E-06*(DATA_CACHE_REFILLS_L2_ALL+DATA_CACHE_EVICTED_ALL)*64/time +L2 data volume [GBytes] = 1.0E-09*(DATA_CACHE_REFILLS_L2_ALL+DATA_CACHE_EVICTED_ALL)*64 +L2 refill bandwidth [MBytes/s] = 1.0E-06*DATA_CACHE_REFILLS_L2_ALL*64/time +L2 evict [MBytes/s] = 1.0E-06*DATA_CACHE_EVICTED_ALL*64/time +- +Profiling group to measure L2 cache bandwidth. The bandwidth is +computed by the number of cache line loaded from L2 to L1 and the +number of modified cache lines evicted from the L1. +Note that this bandwidth also includes data transfers due to a +write allocate load on a store miss in L1 and copy back transfers if +originated from L2. + + + diff --git a/collectors/likwid/groups/kabini/BRANCH.txt b/collectors/likwid/groups/kabini/BRANCH.txt new file mode 100644 index 0000000..7495b74 --- /dev/null +++ b/collectors/likwid/groups/kabini/BRANCH.txt @@ -0,0 +1,26 @@ +SHORT Branch prediction miss rate/ratio + +EVENTSET +PMC0 RETIRED_INSTRUCTIONS +PMC1 RETIRED_BRANCH_INSTR +PMC2 RETIRED_MISPREDICTED_BRANCH_INSTR + +METRICS +Runtime (RDTSC) [s] time +Branch rate PMC1/PMC0 +Branch misprediction rate PMC2/PMC0 +Branch misprediction ratio PMC2/PMC1 +Instructions per branch PMC0/PMC1 + +LONG +Formulas: +Branch rate = RETIRED_BRANCH_INSTR/RETIRED_INSTRUCTIONS +Branch misprediction rate = RETIRED_MISPREDICTED_BRANCH_INSTR/RETIRED_INSTRUCTIONS +Branch misprediction ratio = RETIRED_MISPREDICTED_BRANCH_INSTR/RETIRED_BRANCH_INSTR +Instructions per branch = RETIRED_INSTRUCTIONS/RETIRED_BRANCH_INSTR +- +The rates state how often on average a branch or a mispredicted branch occurred +per instruction retired in total. The branch misprediction ratio sets directly +into relation what ratio of all branch instruction where mispredicted. +Instructions per branch is 1/branch rate. + diff --git a/collectors/likwid/groups/kabini/CACHE.txt b/collectors/likwid/groups/kabini/CACHE.txt new file mode 100644 index 0000000..8a59288 --- /dev/null +++ b/collectors/likwid/groups/kabini/CACHE.txt @@ -0,0 +1,32 @@ +SHORT Data cache miss rate/ratio + +EVENTSET +PMC0 RETIRED_INSTRUCTIONS +PMC1 DATA_CACHE_ACCESSES +PMC2 DATA_CACHE_REFILLS_ALL +PMC3 DATA_CACHE_REFILLS_NB_ALL + +METRICS +Runtime (RDTSC) [s] time +data cache misses PMC2+PMC3 +data cache request rate PMC1/PMC0 +data cache miss rate (PMC2+PMC3)/PMC0 +data cache miss ratio (PMC2+PMC3)/PMC1 + +LONG +Formulas: +data cache misses = DATA_CACHE_REFILLS_ALL + DATA_CACHE_REFILLS_NB_ALL +data cache request rate = DATA_CACHE_ACCESSES / RETIRED_INSTRUCTIONS +data cache miss rate = (DATA_CACHE_REFILLS_ALL + DATA_CACHE_REFILLS_NB_ALL)/RETIRED_INSTRUCTIONS +data cache miss ratio = (DATA_CACHE_REFILLS_ALL + DATA_CACHE_REFILLS_NB_ALL)/DATA_CACHE_ACCESSES +- +This group measures the locality of your data accesses with regard to the +L1 cache. Data cache request rate tells you how data intensive your code is +or how many data accesses you have on average per instruction. +The data cache miss rate gives a measure how often it was necessary to get +cache lines from higher levels of the memory hierarchy. And finally +data cache miss ratio tells you how many of your memory references required +a cache line to be loaded from a higher level. While the# data cache miss rate +might be given by your algorithm you should try to get data cache miss ratio +as low as possible by increasing your cache reuse. + diff --git a/collectors/likwid/groups/kabini/CPI.txt b/collectors/likwid/groups/kabini/CPI.txt new file mode 100644 index 0000000..c0746e7 --- /dev/null +++ b/collectors/likwid/groups/kabini/CPI.txt @@ -0,0 +1,26 @@ +SHORT Cycles per instruction + +EVENTSET +PMC0 RETIRED_INSTRUCTIONS +PMC1 CPU_CLOCKS_UNHALTED +PMC2 RETIRED_UOPS + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] PMC1*inverseClock +CPI PMC1/PMC0 +CPI (based on uops) PMC1/PMC2 +IPC PMC0/PMC1 + +LONG +Formulas: +CPI = CPU_CLOCKS_UNHALTED/RETIRED_INSTRUCTIONS +CPI (based on uops) = CPU_CLOCKS_UNHALTED/RETIRED_UOPS +IPC = RETIRED_INSTRUCTIONS/CPU_CLOCKS_UNHALTED +- +This group measures how efficient the processor works with +regard to instruction throughput. Also important as a standalone +metric is RETIRED_INSTRUCTIONS as it tells you how many instruction +you need to execute for a task. An optimization might show very +low CPI values but execute many more instruction for it. + diff --git a/collectors/likwid/groups/kabini/DATA.txt b/collectors/likwid/groups/kabini/DATA.txt new file mode 100644 index 0000000..75f1f60 --- /dev/null +++ b/collectors/likwid/groups/kabini/DATA.txt @@ -0,0 +1,16 @@ +SHORT Load to store ratio + +EVENTSET +PMC0 LS_DISPATCH_LOADS +PMC1 LS_DISPATCH_STORES + +METRICS +Runtime (RDTSC) [s] time +Load to store ratio PMC0/PMC1 + +LONG +Formulas: +Load to store ratio = LS_DISPATCH_LOADS/LS_DISPATCH_STORES +- +This is a simple metric to determine your load to store ratio. + diff --git a/collectors/likwid/groups/kabini/FLOPS_DP.txt b/collectors/likwid/groups/kabini/FLOPS_DP.txt new file mode 100644 index 0000000..1a4e54c --- /dev/null +++ b/collectors/likwid/groups/kabini/FLOPS_DP.txt @@ -0,0 +1,26 @@ +SHORT Double Precision MFLOP/s + +EVENTSET +PMC0 RETIRED_INSTRUCTIONS +PMC1 CPU_CLOCKS_UNHALTED +PMC2 RETIRED_UOPS +PMC3 RETIRED_FLOPS_DOUBLE_ALL + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] PMC1*inverseClock +DP [MFLOP/s] 1.0E-06*(PMC3)/time +CPI PMC1/PMC0 +CPI (based on uops) PMC1/PMC2 +IPC PMC0/PMC1 + +LONG +Formulas: +DP [MFLOP/s] = 1.0E-06*(RETIRED_FLOPS_DOUBLE_ALL)/time +CPI = CPU_CLOCKS_UNHALTED/RETIRED_INSTRUCTIONS +CPI (based on uops) = CPU_CLOCKS_UNHALTED/RETIRED_UOPS +IPC = RETIRED_INSTRUCTIONS/CPU_CLOCKS_UNHALTED +- +Profiling group to measure double precisision FLOP rate. + + diff --git a/collectors/likwid/groups/kabini/FLOPS_SP.txt b/collectors/likwid/groups/kabini/FLOPS_SP.txt new file mode 100644 index 0000000..f6c08c1 --- /dev/null +++ b/collectors/likwid/groups/kabini/FLOPS_SP.txt @@ -0,0 +1,26 @@ +SHORT Single Precision MFLOP/s + +EVENTSET +PMC0 RETIRED_INSTRUCTIONS +PMC1 CPU_CLOCKS_UNHALTED +PMC2 RETIRED_UOPS +PMC3 RETIRED_FLOPS_SINGLE_ALL + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] PMC1*inverseClock +SP [MFLOP/s] 1.0E-06*(PMC3)/time +CPI PMC1/PMC0 +CPI (based on uops) PMC1/PMC2 +IPC PMC0/PMC1 + +LONG +Formulas: +SP [MFLOP/s] = 1.0E-06*(RETIRED_FLOPS_SINGLE_ALL)/time +CPI = CPU_CLOCKS_UNHALTED/RETIRED_INSTRUCTIONS +CPI (based on uops) = CPU_CLOCKS_UNHALTED/RETIRED_UOPS +IPC = RETIRED_INSTRUCTIONS/CPU_CLOCKS_UNHALTED +- +Profiling group to measure single precision FLOP rate. + + diff --git a/collectors/likwid/groups/kabini/FPU_EXCEPTION.txt b/collectors/likwid/groups/kabini/FPU_EXCEPTION.txt new file mode 100644 index 0000000..5ed02c6 --- /dev/null +++ b/collectors/likwid/groups/kabini/FPU_EXCEPTION.txt @@ -0,0 +1,21 @@ +SHORT Floating point exceptions + +EVENTSET +PMC0 RETIRED_INSTRUCTIONS +PMC1 RETIRED_FP_INSTRUCTIONS_ALL +PMC2 FPU_EXCEPTION_ALL + +METRICS +Runtime (RDTSC) [s] time +Overall FP exception rate PMC2/PMC0 +FP exception rate PMC2/PMC1 + +LONG +Formulas: +Overall FP exception rate = FPU_EXCEPTIONS_ALL / RETIRED_INSTRUCTIONS +FP exception rate = FPU_EXCEPTIONS_ALL / FP_INSTRUCTIONS_RETIRED_ALL +- +Floating point exceptions occur e.g. on the treatment of denormal numbers. +There might be a large penalty if there are too many floating point +exceptions. + diff --git a/collectors/likwid/groups/kabini/ICACHE.txt b/collectors/likwid/groups/kabini/ICACHE.txt new file mode 100644 index 0000000..62b91d6 --- /dev/null +++ b/collectors/likwid/groups/kabini/ICACHE.txt @@ -0,0 +1,23 @@ +SHORT Instruction cache miss rate/ratio + +EVENTSET +PMC0 INSTRUCTION_CACHE_FETCHES +PMC1 INSTRUCTION_CACHE_L2_REFILLS +PMC2 INSTRUCTION_CACHE_SYSTEM_REFILLS +PMC3 RETIRED_INSTRUCTIONS + +METRICS +Runtime (RDTSC) [s] time +L1I request rate PMC0/PMC3 +L1I miss rate (PMC1+PMC2)/PMC3 +L1I miss ratio (PMC1+PMC2)/PMC0 + +LONG +Formulas: +L1I request rate = INSTRUCTION_CACHE_FETCHES / RETIRED_INSTRUCTIONS +L1I miss rate = (INSTRUCTION_CACHE_L2_REFILLS + INSTRUCTION_CACHE_SYSTEM_REFILLS)/RETIRED_INSTRUCTIONS +L1I miss ratio = (INSTRUCTION_CACHE_L2_REFILLS + INSTRUCTION_CACHE_SYSTEM_REFILLS)/INSTRUCTION_CACHE_FETCHES +- +This group measures the locality of your instruction code with regard to the +L1 I-Cache. + diff --git a/collectors/likwid/groups/kabini/L2.txt b/collectors/likwid/groups/kabini/L2.txt new file mode 100644 index 0000000..3598a54 --- /dev/null +++ b/collectors/likwid/groups/kabini/L2.txt @@ -0,0 +1,33 @@ +SHORT L2 cache bandwidth in MBytes/s + +EVENTSET +PMC0 DATA_CACHE_REFILLS_ALL +PMC1 DATA_CACHE_EVICTED_ALL +PMC2 CPU_CLOCKS_UNHALTED + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] PMC2*inverseClock +L2D load bandwidth [MBytes/s] 1.0E-06*PMC0*64.0/time +L2D load data volume [GBytes] 1.0E-09*PMC0*64.0 +L2D evict bandwidth [MBytes/s] 1.0E-06*PMC1*64.0/time +L2D evict data volume [GBytes] 1.0E-09*PMC1*64.0 +L2 bandwidth [MBytes/s] 1.0E-06*(PMC0+PMC1)*64.0/time +L2 data volume [GBytes] 1.0E-09*(PMC0+PMC1)*64.0 + +LONG +Formulas: +L2D load bandwidth [MBytes/s] = 1.0E-06*DATA_CACHE_REFILLS_ALL*64.0/time +L2D load data volume [GBytes] = 1.0E-09*DATA_CACHE_REFILLS_ALL*64.0 +L2D evict bandwidth [MBytes/s] = 1.0E-06*DATA_CACHE_EVICTED_ALL*64.0/time +L2D evict data volume [GBytes] = 1.0E-09*DATA_CACHE_EVICTED_ALL*64.0 +L2 bandwidth [MBytes/s] = 1.0E-06*(DATA_CACHE_REFILLS_ALL+DATA_CACHE_EVICTED_ALL)*64/time +L2 data volume [GBytes] = 1.0E-09*(DATA_CACHE_REFILLS_ALL+DATA_CACHE_EVICTED_ALL)*64 +- +Profiling group to measure L2 cache bandwidth. The bandwidth is +computed by the number of cache line loaded from L2 to L1 and the +number of modified cache lines evicted from the L1. +Note that this bandwidth also includes data transfers due to a +write allocate load on a store miss in L1 and copy back transfers if +originated from L2. + diff --git a/collectors/likwid/groups/kabini/MEM.txt b/collectors/likwid/groups/kabini/MEM.txt new file mode 100644 index 0000000..2fa9dfe --- /dev/null +++ b/collectors/likwid/groups/kabini/MEM.txt @@ -0,0 +1,20 @@ +SHORT Main memory bandwidth in MBytes/s + +EVENTSET +UPMC0 UNC_DRAM_ACCESSES_DCT0_ALL +UPMC1 UNC_DRAM_ACCESSES_DCT1_ALL + +METRICS +Runtime (RDTSC) [s] time +Memory bandwidth [MBytes/s] 1.0E-06*(UPMC0+UPMC1)*64.0/time +Memory data volume [GBytes] 1.0E-09*(UPMC0+UPMC1)*64.0 + +LONG +Formulas: +Memory bandwidth [MBytes/s] = 1.0E-06*(DRAM_ACCESSES_DCTO_ALL+DRAM_ACCESSES_DCT1_ALL)*64/time +Memory data volume [GBytes] = 1.0E-09*(DRAM_ACCESSES_DCTO_ALL+DRAM_ACCESSES_DCT1_ALL)*64 +- +Profiling group to measure memory bandwidth drawn by all cores of a socket. +Note: As this group measures the accesses from all cores it only makes sense +to measure with one core per socket, similar as with the Intel Nehalem Uncore events. + diff --git a/collectors/likwid/groups/kabini/NUMA_0_3.txt b/collectors/likwid/groups/kabini/NUMA_0_3.txt new file mode 100644 index 0000000..79f3618 --- /dev/null +++ b/collectors/likwid/groups/kabini/NUMA_0_3.txt @@ -0,0 +1,28 @@ +SHORT Read/Write Events between the ccNUMA nodes + +EVENTSET +UPMC0 UNC_CPU_TO_DRAM_LOCAL_TO_0 +UPMC1 UNC_CPU_TO_DRAM_LOCAL_TO_1 +UPMC2 UNC_CPU_TO_DRAM_LOCAL_TO_2 +UPMC3 UNC_CPU_TO_DRAM_LOCAL_TO_3 + +METRICS +Runtime (RDTSC) [s] time +DRAM read/write local to 0 [MegaEvents/s] 1.0E-06*UPMC0/time +DRAM read/write local to 1 [MegaEvents/s] 1.0E-06*UPMC1/time +DRAM read/write local to 2 [MegaEvents/s] 1.0E-06*UPMC2/time +DRAM read/write local to 3 [MegaEvents/s] 1.0E-06*UPMC3/time + +LONG +Formulas: +DRAM read/write local to 0 [MegaEvents/s] = 1.0E-06*UNC_CPU_TO_DRAM_LOCAL_TO_0/time +DRAM read/write local to 1 [MegaEvents/s] = 1.0E-06*UNC_CPU_TO_DRAM_LOCAL_TO_1/time +DRAM read/write local to 2 [MegaEvents/s] = 1.0E-06*UNC_CPU_TO_DRAM_LOCAL_TO_2/time +DRAM read/write local to 3 [MegaEvents/s] = 1.0E-06*UNC_CPU_TO_DRAM_LOCAL_TO_3/time +- +Profiling group to measure the traffic from local CPU to the different +DRAM NUMA nodes. This group allows to detect NUMA problems in a threaded +code. You must first determine on which memory domains your code is running. +A code should only have significant traffic to its own memory domain. + + diff --git a/collectors/likwid/groups/kabini/NUMA_4_7.txt b/collectors/likwid/groups/kabini/NUMA_4_7.txt new file mode 100644 index 0000000..7b518db --- /dev/null +++ b/collectors/likwid/groups/kabini/NUMA_4_7.txt @@ -0,0 +1,28 @@ +SHORT Read/Write Events between the ccNUMA nodes + +EVENTSET +UPMC0 UNC_CPU_TO_DRAM_LOCAL_TO_4 +UPMC1 UNC_CPU_TO_DRAM_LOCAL_TO_5 +UPMC2 UNC_CPU_TO_DRAM_LOCAL_TO_6 +UPMC3 UNC_CPU_TO_DRAM_LOCAL_TO_7 + +METRICS +Runtime (RDTSC) [s] time +DRAM read/write local to 4 [MegaEvents/s] 1.0E-06*UPMC0/time +DRAM read/write local to 5 [MegaEvents/s] 1.0E-06*UPMC1/time +DRAM read/write local to 6 [MegaEvents/s] 1.0E-06*UPMC2/time +DRAM read/write local to 7 [MegaEvents/s] 1.0E-06*UPMC3/time + +LONG +Formulas: +DRAM read/write local to 4 [MegaEvents/s] = 1.0E-06*UNC_CPU_TO_DRAM_LOCAL_TO_4/time +DRAM read/write local to 5 [MegaEvents/s] = 1.0E-06*UNC_CPU_TO_DRAM_LOCAL_TO_5/time +DRAM read/write local to 6 [MegaEvents/s] = 1.0E-06*UNC_CPU_TO_DRAM_LOCAL_TO_6/time +DRAM read/write local to 7 [MegaEvents/s] = 1.0E-06*UNC_CPU_TO_DRAM_LOCAL_TO_7/time +- +Profiling group to measure the traffic from local CPU to the different +DRAM NUMA nodes. This group allows to detect NUMA problems in a threaded +code. You must first determine on which memory domains your code is running. +A code should only have significant traffic to its own memory domain. + + diff --git a/collectors/likwid/groups/kabini/TLB.txt b/collectors/likwid/groups/kabini/TLB.txt new file mode 100644 index 0000000..f66b3cb --- /dev/null +++ b/collectors/likwid/groups/kabini/TLB.txt @@ -0,0 +1,34 @@ +SHORT TLB miss rate/ratio + +EVENTSET +PMC0 RETIRED_INSTRUCTIONS +PMC1 DATA_CACHE_ACCESSES +PMC2 L2_DTLB_HIT_ALL +PMC3 DTLB_MISS_ALL + +METRICS +Runtime (RDTSC) [s] time +L1 DTLB request rate PMC1/PMC0 +L1 DTLB miss rate (PMC2+PMC3)/PMC0 +L1 DTLB miss ratio (PMC2+PMC3)/PMC1 +L2 DTLB request rate (PMC2+PMC3)/PMC0 +L2 DTLB miss rate PMC3/PMC0 +L2 DTLB miss ratio PMC3/(PMC2+PMC3) + + +LONG +Formulas: +L1 DTLB request rate = DATA_CACHE_ACCESSES / RETIRED_INSTRUCTIONS +L1 DTLB miss rate = (L2_DTLB_HIT_ALL+DTLB_MISS_ALL)/RETIRED_INSTRUCTIONS +L1 DTLB miss ratio = (L2_DTLB_HIT_ALL+DTLB_MISS_ALL)/DATA_CACHE_ACCESSES +L2 DTLB request rate = (L2_DTLB_HIT_ALL+DTLB_MISS_ALL)/RETIRED_INSTRUCTIONS +L2 DTLB miss rate = DTLB_MISS_ALL / RETIRED_INSTRUCTIONS +L2 DTLB miss ratio = DTLB_MISS_ALL / (L2_DTLB_HIT_ALL+DTLB_MISS_ALL) +- +L1 DTLB request rate tells you how data intensive your code is +or how many data accesses you have on average per instruction. +The DTLB miss rate gives a measure how often a TLB miss occurred +per instruction. And finally L1 DTLB miss ratio tells you how many +of your memory references required caused a TLB miss on average. +NOTE: The L2 metrics are only relevant if L2 DTLB request rate is +equal to the L1 DTLB miss rate! diff --git a/collectors/likwid/groups/knl/BRANCH.txt b/collectors/likwid/groups/knl/BRANCH.txt new file mode 100644 index 0000000..b8d41b2 --- /dev/null +++ b/collectors/likwid/groups/knl/BRANCH.txt @@ -0,0 +1,31 @@ +SHORT Branch prediction miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 BR_INST_RETIRED_ALL_BRANCHES +PMC1 BR_MISP_RETIRED_ALL_BRANCHES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Branch rate PMC0/FIXC0 +Branch misprediction rate PMC1/FIXC0 +Branch misprediction ratio PMC1/PMC0 +Instructions per branch FIXC0/PMC0 + +LONG +Formulas: +Branch rate = BR_INST_RETIRED_ALL_BRANCHES/INSTR_RETIRED_ANY +Branch misprediction rate = BR_MISP_RETIRED_ALL_BRANCHES/INSTR_RETIRED_ANY +Branch misprediction ratio = BR_MISP_RETIRED_ALL_BRANCHES/BR_INST_RETIRED_ALL_BRANCHES +Instructions per branch = INSTR_RETIRED_ANY/BR_INST_RETIRED_ALL_BRANCHES +- +The rates state how often on average a branch or a mispredicted branch occurred +per instruction retired in total. The branch misprediction ratio sets directly +into relation what ratio of all branch instruction where mispredicted. +Instructions per branch is 1/branch rate. + diff --git a/collectors/likwid/groups/knl/CLOCK.txt b/collectors/likwid/groups/knl/CLOCK.txt new file mode 100644 index 0000000..8756ef2 --- /dev/null +++ b/collectors/likwid/groups/knl/CLOCK.txt @@ -0,0 +1,23 @@ +SHORT Power and Energy consumption + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PWR0 PWR_PKG_ENERGY + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Energy [J] PWR0 +Power [W] PWR0/time + +LONG +Formulas: +Power = PWR_PKG_ENERGY / time +- +The Xeon Phi (Knights Landing) implements the new RAPL interface. This interface enables to +monitor the consumed energy on the package (socket) level. + diff --git a/collectors/likwid/groups/knl/DATA.txt b/collectors/likwid/groups/knl/DATA.txt new file mode 100644 index 0000000..61a915b --- /dev/null +++ b/collectors/likwid/groups/knl/DATA.txt @@ -0,0 +1,22 @@ +SHORT Load to store ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 MEM_UOPS_RETIRED_ALL_LOADS +PMC1 MEM_UOPS_RETIRED_ALL_STORES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Load to store ratio PMC0/PMC1 + +LONG +Formulas: +Load to store ratio = MEM_UOPS_RETIRED_ALL_LOADS/MEM_UOPS_RETIRED_ALL_STORES +- +This is a metric to determine your load to store ratio. + diff --git a/collectors/likwid/groups/knl/DIVIDE.txt b/collectors/likwid/groups/knl/DIVIDE.txt new file mode 100644 index 0000000..d9b0918 --- /dev/null +++ b/collectors/likwid/groups/knl/DIVIDE.txt @@ -0,0 +1,24 @@ +SHORT Divide unit information + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 CYCLES_DIV_BUSY_COUNT +PMC1 CYCLES_DIV_BUSY + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Number of divide ops PMC0 +Avg. divide unit usage duration PMC1/PMC0 + +LONG +Formulas: +Number of divide ops = CYCLES_DIV_BUSY_COUNT +Avg. divide unit usage duration = CYCLES_DIV_BUSY/CYCLES_DIV_BUSY_COUNT +- +This performance group measures the average latency of divide operations diff --git a/collectors/likwid/groups/knl/ENERGY.txt b/collectors/likwid/groups/knl/ENERGY.txt new file mode 100644 index 0000000..19ede75 --- /dev/null +++ b/collectors/likwid/groups/knl/ENERGY.txt @@ -0,0 +1,33 @@ +SHORT Power and Energy consumption + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +TMP0 TEMP_CORE +PWR0 PWR_PKG_ENERGY +PWR1 PWR_PP0_ENERGY +PWR3 PWR_DRAM_ENERGY + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Temperature [C] TMP0 +Energy [J] PWR0 +Power [W] PWR0/time +Energy PP0 [J] PWR1 +Power PP0 [W] PWR1/time +Energy DRAM [J] PWR3 +Power DRAM [W] PWR3/time + +LONG +Formulas: +Power = PWR_PKG_ENERGY / time +Power PP0 = PWR_PP0_ENERGY / time +Power DRAM = PWR_DRAM_ENERGY / time +- +Knights Landing implements the new RAPL interface. This interface enables to +monitor the consumed energy on the package (socket) level. + diff --git a/collectors/likwid/groups/knl/FLOPS_DP.txt b/collectors/likwid/groups/knl/FLOPS_DP.txt new file mode 100644 index 0000000..88bffe2 --- /dev/null +++ b/collectors/likwid/groups/knl/FLOPS_DP.txt @@ -0,0 +1,34 @@ +SHORT Double Precision MFLOP/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 UOPS_RETIRED_SCALAR_SIMD +PMC1 UOPS_RETIRED_PACKED_SIMD + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +DP [MFLOP/s] (SSE assumed) 1.0E-06*((PMC1*2.0)+PMC0)/time +DP [MFLOP/s] (AVX assumed) 1.0E-06*((PMC1*4.0)+PMC0)/time +DP [MFLOP/s] (AVX512 assumed) 1.0E-06*((PMC1*8.0)+PMC0)/time +Packed [MUOPS/s] 1.0E-06*(PMC1)/time +Scalar [MUOPS/s] 1.0E-06*PMC0/time + +LONG +Formulas: +DP [MFLOP/s] (SSE assumed) = 1.0E-06*(UOPS_RETIRED_PACKED_SIMD*2+UOPS_RETIRED_SCALAR_SIMD)/runtime +DP [MFLOP/s] (AVX assumed) = 1.0E-06*(UOPS_RETIRED_PACKED_SIMD*4+UOPS_RETIRED_SCALAR_SIMD)/runtime +DP [MFLOP/s] (AVX512 assumed) = 1.0E-06*(UOPS_RETIRED_PACKED_SIMD*8+UOPS_RETIRED_SCALAR_SIMD)/runtime +Packed [MUOPS/s] = 1.0E-06*(UOPS_RETIRED_PACKED_SIMD)/runtime +Scalar [MUOPS/s] = 1.0E-06*UOPS_RETIRED_SCALAR_SIMD/runtime +- +AVX/SSE scalar and packed double precision FLOP rates. The Xeon Phi (Knights Landing) provides +no possibility to differentiate between double and single precision FLOP/s. Therefore, we only +assume that the printed [MFLOP/s] value is for double-precision code. Moreover, there is no way +to distinguish between SSE, AVX or AVX512 packed SIMD operations. Therefore, this group prints +out the [MFLOP/s] for different SIMD techniques. +WARNING: The events also count for integer arithmetics diff --git a/collectors/likwid/groups/knl/FLOPS_SP.txt b/collectors/likwid/groups/knl/FLOPS_SP.txt new file mode 100644 index 0000000..4a28116 --- /dev/null +++ b/collectors/likwid/groups/knl/FLOPS_SP.txt @@ -0,0 +1,34 @@ +SHORT Single Precision MFLOP/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 UOPS_RETIRED_SCALAR_SIMD +PMC1 UOPS_RETIRED_PACKED_SIMD + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +SP [MFLOP/s] (SSE assumed) 1.0E-06*(PMC1*4.0+PMC0)/time +SP [MFLOP/s] (AVX assumed) 1.0E-06*(PMC1*8.0+PMC0)/time +SP [MFLOP/s] (AVX512 assumed) 1.0E-06*(PMC1*16.0+PMC0)/time +Packed [MUOPS/s] 1.0E-06*(PMC1)/time +Scalar [MUOPS/s] 1.0E-06*PMC0/time + +LONG +Formulas: +SP [MFLOP/s] (SSE assumed) = 1.0E-06*(UOPS_RETIRED_PACKED_SIMD*4+UOPS_RETIRED_SCALAR_SIMD)/runtime +SP [MFLOP/s] (AVX assumed) = 1.0E-06*(UOPS_RETIRED_PACKED_SIMD*8+UOPS_RETIRED_SCALAR_SIMD)/runtime +SP [MFLOP/s] (AVX512 assumed) = 1.0E-06*(UOPS_RETIRED_PACKED_SIMD*16+UOPS_RETIRED_SCALAR_SIMD)/runtime +Packed [MUOPS/s] = 1.0E-06*(UOPS_RETIRED_PACKED_SIMD)/runtime +Scalar [MUOPS/s] = 1.0E-06*UOPS_RETIRED_SCALAR_SIMD/runtime +- +AVX/SSE scalar and packed single precision FLOP rates. The Xeon Phi (Knights Landing) provides +no possibility to differentiate between double and single precision FLOP/s. Therefore, we only +assume that the printed MFLOP/s value is for single-precision code. Moreover, there is no way +to distinguish between SSE, AVX or AVX512 packed SIMD operations. Therefore, this group prints +out the MFLOP/s for different SIMD techniques. +WARNING: The events also count for integer arithmetics diff --git a/collectors/likwid/groups/knl/FRONTEND_STALLS.txt b/collectors/likwid/groups/knl/FRONTEND_STALLS.txt new file mode 100644 index 0000000..1b9f98e --- /dev/null +++ b/collectors/likwid/groups/knl/FRONTEND_STALLS.txt @@ -0,0 +1,25 @@ +SHORT Frontend stalls + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 NO_ALLOC_CYCLES_ALL +PMC1 NO_ALLOC_CYCLES_ALL_COUNT + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Frontend stalls PMC1 +Avg. frontend stall duration [cyc] PMC0/PMC1 +Frontend stall ratio PMC0/FIXC1 + +LONG +Formulas: +Frontend stalls = NO_ALLOC_CYCLES_ALL +Avg. frontend stall duration [cyc] = NO_ALLOC_CYCLES_ALL/NO_ALLOC_CYCLES_ALL_COUNT +Frontend stall ratio = NO_ALLOC_CYCLES_ALL/CPU_CLK_UNHALTED_CORE +- +Frontend stalls diff --git a/collectors/likwid/groups/knl/HBM.txt b/collectors/likwid/groups/knl/HBM.txt new file mode 100644 index 0000000..ac44418 --- /dev/null +++ b/collectors/likwid/groups/knl/HBM.txt @@ -0,0 +1,46 @@ +SHORT Memory bandwidth in MBytes/s for High Bandwidth Memory (HBM) + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +EDBOX0C0 EDC_RPQ_INSERTS +EDBOX1C0 EDC_RPQ_INSERTS +EDBOX2C0 EDC_RPQ_INSERTS +EDBOX3C0 EDC_RPQ_INSERTS +EDBOX4C0 EDC_RPQ_INSERTS +EDBOX5C0 EDC_RPQ_INSERTS +EDBOX6C0 EDC_RPQ_INSERTS +EDBOX7C0 EDC_RPQ_INSERTS +EDBOX0C1 EDC_WPQ_INSERTS +EDBOX1C1 EDC_WPQ_INSERTS +EDBOX2C1 EDC_WPQ_INSERTS +EDBOX3C1 EDC_WPQ_INSERTS +EDBOX4C1 EDC_WPQ_INSERTS +EDBOX5C1 EDC_WPQ_INSERTS +EDBOX6C1 EDC_WPQ_INSERTS +EDBOX7C1 EDC_WPQ_INSERTS + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Memory read bandwidth [MBytes/s] 1.0E-06*(EDBOX0C0+EDBOX1C0+EDBOX2C0+EDBOX3C0+EDBOX4C0+EDBOX5C0+EDBOX6C0+EDBOX7C0)*64.0/time +Memory read data volume [GBytes] 1.0E-09*(EDBOX0C0+EDBOX1C0+EDBOX2C0+EDBOX3C0+EDBOX4C0+EDBOX5C0+EDBOX6C0+EDBOX7C0)*64.0 +Memory writeback bandwidth [MBytes/s] 1.0E-06*(EDBOX0C1+EDBOX1C1+EDBOX2C1+EDBOX3C1+EDBOX4C1+EDBOX5C1+EDBOX6C1+EDBOX7C1)*64.0/time +Memory writeback data volume [GBytes] 1.0E-09*(EDBOX0C1+EDBOX1C1+EDBOX2C1+EDBOX3C1+EDBOX4C1+EDBOX5C1+EDBOX6C1+EDBOX7C1)*64.0 +Memory bandwidth [MBytes/s] 1.0E-06*(EDBOX0C0+EDBOX1C0+EDBOX2C0+EDBOX3C0+EDBOX4C0+EDBOX5C0+EDBOX6C0+EDBOX7C0+EDBOX0C1+EDBOX1C1+EDBOX2C1+EDBOX3C1+EDBOX4C1+EDBOX5C1+EDBOX6C1+EDBOX7C1)*64.0/time +Memory data volume [GBytes] 1.0E-09*(EDBOX0C0+EDBOX1C0+EDBOX2C0+EDBOX3C0+EDBOX4C0+EDBOX5C0+EDBOX6C0+EDBOX7C0+EDBOX0C1+EDBOX1C1+EDBOX2C1+EDBOX3C1+EDBOX4C1+EDBOX5C1+EDBOX6C1+EDBOX7C1)*64.0 + +LONG +Formulas: +Memory read bandwidth [MBytes/s] = 1.0E-06*(sum(EDC_RPQ_INSERTS))*64/time +Memory read data volume [GBytes] = 1.0E-09*(sum(EDC_RPQ_INSERTS))*64 +Memory writeback bandwidth [MBytes/s] = 1.0E-06*(sum(EDC_WPQ_INSERTS))*64/time +Memory writeback data volume [GBytes] = 1.0E-09*(sum(EDC_WPQ_INSERTS))*64 +Memory bandwidth [MBytes/s] = 1.0E-06*(sum(EDC_RPQ_INSERTS)+sum(EDC_WPQ_INSERTS))*64/time +Memory data volume [GBytes] = 1.0E-09*(sum(EDC_RPQ_INSERTS)+sum(EDC_WPQ_INSERTS))*64 +- +Profiling group to measure data transfers from and to the high bandwidth memory (HBM). + diff --git a/collectors/likwid/groups/knl/HBM_CACHE.txt b/collectors/likwid/groups/knl/HBM_CACHE.txt new file mode 100644 index 0000000..f89af5d --- /dev/null +++ b/collectors/likwid/groups/knl/HBM_CACHE.txt @@ -0,0 +1,87 @@ +SHORT Memory bandwidth in MBytes/s for High Bandwidth Memory (HBM) + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +EDBOX0C0 EDC_RPQ_INSERTS +EDBOX1C0 EDC_RPQ_INSERTS +EDBOX2C0 EDC_RPQ_INSERTS +EDBOX3C0 EDC_RPQ_INSERTS +EDBOX4C0 EDC_RPQ_INSERTS +EDBOX5C0 EDC_RPQ_INSERTS +EDBOX6C0 EDC_RPQ_INSERTS +EDBOX7C0 EDC_RPQ_INSERTS +EDBOX0C1 EDC_WPQ_INSERTS +EDBOX1C1 EDC_WPQ_INSERTS +EDBOX2C1 EDC_WPQ_INSERTS +EDBOX3C1 EDC_WPQ_INSERTS +EDBOX4C1 EDC_WPQ_INSERTS +EDBOX5C1 EDC_WPQ_INSERTS +EDBOX6C1 EDC_WPQ_INSERTS +EDBOX7C1 EDC_WPQ_INSERTS +EUBOX0C0 EDC_MISS_CLEAN +EUBOX1C0 EDC_MISS_CLEAN +EUBOX2C0 EDC_MISS_CLEAN +EUBOX3C0 EDC_MISS_CLEAN +EUBOX4C0 EDC_MISS_CLEAN +EUBOX5C0 EDC_MISS_CLEAN +EUBOX6C0 EDC_MISS_CLEAN +EUBOX7C0 EDC_MISS_CLEAN +EUBOX0C1 EDC_MISS_DIRTY +EUBOX1C1 EDC_MISS_DIRTY +EUBOX2C1 EDC_MISS_DIRTY +EUBOX3C1 EDC_MISS_DIRTY +EUBOX4C1 EDC_MISS_DIRTY +EUBOX5C1 EDC_MISS_DIRTY +EUBOX6C1 EDC_MISS_DIRTY +EUBOX7C1 EDC_MISS_DIRTY +MBOX0C0 MC_CAS_READS +MBOX0C1 MC_CAS_WRITES +MBOX1C0 MC_CAS_READS +MBOX1C1 MC_CAS_WRITES +MBOX2C0 MC_CAS_READS +MBOX2C1 MC_CAS_WRITES +MBOX4C0 MC_CAS_READS +MBOX4C1 MC_CAS_WRITES +MBOX5C0 MC_CAS_READS +MBOX5C1 MC_CAS_WRITES +MBOX6C0 MC_CAS_READS +MBOX6C1 MC_CAS_WRITES + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +MCDRAM Memory read bandwidth [MBytes/s] 1.0E-06*((EDBOX0C0+EDBOX1C0+EDBOX2C0+EDBOX3C0+EDBOX4C0+EDBOX5C0+EDBOX6C0+EDBOX7C0)-(EUBOX0C0+EUBOX1C0+EUBOX2C0+EUBOX3C0+EUBOX4C0+EUBOX5C0+EUBOX6C0+EUBOX7C0)-(EUBOX0C1+EUBOX1C1+EUBOX2C1+EUBOX3C1+EUBOX4C1+EUBOX5C1+EUBOX6C1+EUBOX7C1))*64.0/time +MCDRAM Memory read data volume [GBytes] 1.0E-09*((EDBOX0C0+EDBOX1C0+EDBOX2C0+EDBOX3C0+EDBOX4C0+EDBOX5C0+EDBOX6C0+EDBOX7C0)-(EUBOX0C0+EUBOX1C0+EUBOX2C0+EUBOX3C0+EUBOX4C0+EUBOX5C0+EUBOX6C0+EUBOX7C0)-(EUBOX0C1+EUBOX1C1+EUBOX2C1+EUBOX3C1+EUBOX4C1+EUBOX5C1+EUBOX6C1+EUBOX7C1))*64.0 +MCDRAM Memory writeback bandwidth [MBytes/s] 1.0E-06*((EDBOX0C1+EDBOX1C1+EDBOX2C1+EDBOX3C1+EDBOX4C1+EDBOX5C1+EDBOX6C1+EDBOX7C1)-(MBOX0C0+MBOX1C0+MBOX2C0+MBOX4C0+MBOX5C0+MBOX6C0))*64.0/time +MCDRAM Memory writeback data volume [GBytes] 1.0E-09*((EDBOX0C1+EDBOX1C1+EDBOX2C1+EDBOX3C1+EDBOX4C1+EDBOX5C1+EDBOX6C1+EDBOX7C1)-(MBOX0C0+MBOX1C0+MBOX2C0+MBOX4C0+MBOX5C0+MBOX6C0))*64.0 +MCDRAM Memory bandwidth [MBytes/s] 1.0E-06*(((EDBOX0C0+EDBOX1C0+EDBOX2C0+EDBOX3C0+EDBOX4C0+EDBOX5C0+EDBOX6C0+EDBOX7C0)-(EUBOX0C0+EUBOX1C0+EUBOX2C0+EUBOX3C0+EUBOX4C0+EUBOX5C0+EUBOX6C0+EUBOX7C0)-(EUBOX0C1+EUBOX1C1+EUBOX2C1+EUBOX3C1+EUBOX4C1+EUBOX5C1+EUBOX6C1+EUBOX7C1))+((EDBOX0C1+EDBOX1C1+EDBOX2C1+EDBOX3C1+EDBOX4C1+EDBOX5C1+EDBOX6C1+EDBOX7C1)-(MBOX0C0+MBOX1C0+MBOX2C0+MBOX4C0+MBOX5C0+MBOX6C0)))*64.0/time +MCDRAM Memory data volume [GBytes] 1.0E-09*(((EDBOX0C0+EDBOX1C0+EDBOX2C0+EDBOX3C0+EDBOX4C0+EDBOX5C0+EDBOX6C0+EDBOX7C0)-(EUBOX0C0+EUBOX1C0+EUBOX2C0+EUBOX3C0+EUBOX4C0+EUBOX5C0+EUBOX6C0+EUBOX7C0)-(EUBOX0C1+EUBOX1C1+EUBOX2C1+EUBOX3C1+EUBOX4C1+EUBOX5C1+EUBOX6C1+EUBOX7C1))+((EDBOX0C1+EDBOX1C1+EDBOX2C1+EDBOX3C1+EDBOX4C1+EDBOX5C1+EDBOX6C1+EDBOX7C1)-(MBOX0C0+MBOX1C0+MBOX2C0+MBOX4C0+MBOX5C0+MBOX6C0)))*64.0 +DDR Memory read bandwidth [MBytes/s] 1.0E-06*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX4C0+MBOX5C0+MBOX6C0)*64.0/time +DDR Memory read data volume [GBytes] 1.0E-09*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX4C0+MBOX5C0+MBOX6C0)*64.0 +DDR Memory writeback bandwidth [MBytes/s] 1.0E-06*(MBOX0C1+MBOX1C1+MBOX2C1+MBOX4C1+MBOX5C1+MBOX6C1)*64.0/time +DDR Memory writeback data volume [GBytes] 1.0E-09*(MBOX0C1+MBOX1C1+MBOX2C1+MBOX4C1+MBOX5C1+MBOX6C1)*64.0 +DDR Memory bandwidth [MBytes/s] 1.0E-06*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX4C0+MBOX5C0+MBOX6C0+MBOX0C1+MBOX1C1+MBOX2C1+MBOX4C1+MBOX5C1+MBOX6C1)*64.0/time +DDR Memory data volume [GBytes] 1.0E-09*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX4C0+MBOX5C0+MBOX6C0+MBOX0C1+MBOX1C1+MBOX2C1+MBOX4C1+MBOX5C1+MBOX6C1)*64.0 + + +LONG +Formulas: +MCDRAM Memory read bandwidth [MBytes/s] = 1.0E-06*(sum(EDC_RPQ_INSERTS))*64/time +MCDRAM Memory read data volume [GBytes] = 1.0E-09*(sum(EDC_RPQ_INSERTS))*64 +MCDRAM Memory writeback bandwidth [MBytes/s] = 1.0E-06*(sum(EDC_WPQ_INSERTS))*64/time +MCDRAM Memory writeback data volume [GBytes] = 1.0E-09*(sum(EDC_WPQ_INSERTS))*64 +MCDRAM Memory bandwidth [MBytes/s] = 1.0E-06*(sum(EDC_RPQ_INSERTS)+sum(EDC_WPQ_INSERTS))*64/time +MCDRAM Memory data volume [GBytes] = 1.0E-09*(sum(EDC_RPQ_INSERTS)+sum(EDC_WPQ_INSERTS))*64 +DDR Memory read bandwidth [MBytes/s] = 1.0E-06*(sum(MC_CAS_READS))*64/time +DDR Memory read data volume [GBytes] = 1.0E-09*(sum(MC_CAS_READS))*64 +DDR Memory writeback bandwidth [MBytes/s] = 1.0E-06*(sum(MC_CAS_WRITES))*64/time +DDR Memory writeback data volume [GBytes] = 1.0E-09*(sum(MC_CAS_WRITES))*64 +DDR Memory bandwidth [MBytes/s] = 1.0E-06*(sum(MC_CAS_READS)+sum(MC_CAS_WRITES))*64/time +DDR Memory data volume [GBytes] = 1.0E-09*(sum(MC_CAS_READS)+sum(MC_CAS_WRITES))*64 +- +Profiling group to measure data transfers from and to the high bandwidth memory (HBM). diff --git a/collectors/likwid/groups/knl/HBM_OFFCORE.txt b/collectors/likwid/groups/knl/HBM_OFFCORE.txt new file mode 100644 index 0000000..626d08f --- /dev/null +++ b/collectors/likwid/groups/knl/HBM_OFFCORE.txt @@ -0,0 +1,32 @@ +SHORT Memory bandwidth in MBytes/s for High Bandwidth Memory (HBM) + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0:MATCH0=0x4908:MATCH1=0x3F8060 OFFCORE_RESPONSE_0_OPTIONS +PMC1:MATCH0=0x32F7:MATCH1=0x3F8060 OFFCORE_RESPONSE_1_OPTIONS + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Memory read bandwidth [MBytes/s] 1.0E-06*(PMC1)*64.0/time +Memory read data volume [GBytes] 1.0E-09*(PMC1)*64.0 +Memory writeback bandwidth [MBytes/s] 1.0E-06*(PMC0)*64.0/time +Memory writeback data volume [GBytes] 1.0E-09*(PMC0)*64.0 +Memory bandwidth [MBytes/s] 1.0E-06*(PMC0+PMC1)*64.0/time +Memory data volume [GBytes] 1.0E-09*(PMC0+PMC1)*64.0 + +LONG +Formulas: +Memory read bandwidth [MBytes/s] = 1.0E-06*(sum(OFFCORE_RESPONSE_1_OPTIONS:MATCH0=0x32F7:MATCH1=0x3F8060))*64/time +Memory read data volume [GBytes] = 1.0E-09*(sum(OFFCORE_RESPONSE_1_OPTIONS:MATCH0=0x32F7:MATCH1=0x3F8060))*64 +Memory writeback bandwidth [MBytes/s] = 1.0E-06*(sum(OFFCORE_RESPONSE_0_OPTIONS:MATCH0=0x4908:MATCH1=0x3F8060))*64/time +Memory writeback data volume [GBytes] = 1.0E-09*(sum(OFFCORE_RESPONSE_0_OPTIONS:MATCH0=0x4908:MATCH1=0x3F8060))*64 +Memory bandwidth [MBytes/s] = 1.0E-06*(sum(OFFCORE_RESPONSE_1_OPTIONS:MATCH0=0x32F7:MATCH1=0x3F8060)+sum(OFFCORE_RESPONSE_0_OPTIONS:MATCH0=0x4908:MATCH1=0x3F8060))*64/time +Memory data volume [GBytes] = 1.0E-09*(sum(OFFCORE_RESPONSE_1_OPTIONS:MATCH0=0x32F7:MATCH1=0x3F8060)+sum(OFFCORE_RESPONSE_0_OPTIONS:MATCH0=0x4908:MATCH1=0x3F8060))*64 +- +Profiling group to measure data transfers from and to the high bandwidth memory (HBM). +If possible, use the HBM or HBM_CACHE group because they provide more accurate counts. diff --git a/collectors/likwid/groups/knl/ICACHE.txt b/collectors/likwid/groups/knl/ICACHE.txt new file mode 100644 index 0000000..5f11ad6 --- /dev/null +++ b/collectors/likwid/groups/knl/ICACHE.txt @@ -0,0 +1,25 @@ +SHORT Instruction cache miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 ICACHE_ACCESSES +PMC1 ICACHE_MISSES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L1I request rate PMC0/FIXC0 +L1I miss rate PMC1/FIXC0 +L1I miss ratio PMC1/PMC0 + +LONG +Formulas: +L1I request rate = ICACHE_ACCESSES / INSTR_RETIRED_ANY +L1I miss rate = ICACHE_MISSES / INSTR_RETIRED_ANY +L1I miss ratio = ICACHE_MISSES / ICACHE_ACCESSES +- +This group measures some L1 instruction cache metrics. diff --git a/collectors/likwid/groups/knl/L2.txt b/collectors/likwid/groups/knl/L2.txt new file mode 100644 index 0000000..4a9370c --- /dev/null +++ b/collectors/likwid/groups/knl/L2.txt @@ -0,0 +1,36 @@ +SHORT L2 cache bandwidth in MBytes/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 L2_REQUESTS_REFERENCE +PMC1:MATCH0=0x0002:MATCH1=0x1 OFFCORE_RESPONSE_0_OPTIONS + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L2 non-RFO bandwidth [MBytes/s] 1.E-06*(PMC0)*64.0/time +L2 non-RFO data volume [GByte] 1.E-09*PMC0*64.0 +L2 RFO bandwidth [MBytes/s] 1.E-06*(PMC1)*64.0/time +L2 RFO data volume [GByte] 1.E-09*(PMC1)*64.0 +L2 bandwidth [MBytes/s] 1.E-06*(PMC0+PMC1)*64.0/time +L2 data volume [GByte] 1.E-09*(PMC0+PMC1)*64.0 + +LONG +Formulas: +L2 non-RFO bandwidth [MBytes/s] = 1.E-06*L2_REQUESTS_REFERENCE*64.0/time +L2 non-RFO data volume [GByte] = 1.E-09*L2_REQUESTS_REFERENCE*64.0 +L2 RFO bandwidth [MBytes/s] = 1.E-06*(OFFCORE_RESPONSE_0_OPTIONS:MATCH0=0x0002:MATCH1=0x1)*64.0/time +L2 RFO data volume [GByte] = 1.E-09*(OFFCORE_RESPONSE_0_OPTIONS:MATCH0=0x0002:MATCH1=0x1)*64.0 +L2 bandwidth [MBytes/s] = 1.E-06*(L2_REQUESTS_REFERENCE+OFFCORE_RESPONSE_0_OPTIONS:MATCH0=0x0002:MATCH1=0x1)*64.0/time +L2 data volume [GByte] = 1.E-09*(L2_REQUESTS_REFERENCE+OFFCORE_RESPONSE_0_OPTIONS:MATCH0=0x0002:MATCH1=0x1)*64.0 +-- +The L2 bandwidth and data volume does not contain RFOs (also called +write-allocates). The RFO bandwidth and data volume is only accurate when all +used data fits in the L2 cache. As soon as the data exceeds the L2 cache size, +the RFO metrics are too high. +Moreover, with increasing count of measured cores, the non-RFO metrics overcount +but commonly stay withing 10% error. diff --git a/collectors/likwid/groups/knl/L2CACHE.txt b/collectors/likwid/groups/knl/L2CACHE.txt new file mode 100644 index 0000000..e6de92f --- /dev/null +++ b/collectors/likwid/groups/knl/L2CACHE.txt @@ -0,0 +1,34 @@ +SHORT L2 cache miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 MEM_UOPS_RETIRED_L2_HIT_LOADS +PMC1 MEM_UOPS_RETIRED_L2_MISS_LOADS + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L2 request rate (PMC0+PMC1)/FIXC0 +L2 miss rate PMC1/FIXC0 +L2 miss ratio PMC1/(PMC0+PMC1) + +LONG +Formulas: +L2 request rate = (MEM_UOPS_RETIRED_L2_HIT_LOADS+MEM_UOPS_RETIRED_L2_MISS_LOADS)/INSTR_RETIRED_ANY +L2 miss rate = MEM_UOPS_RETIRED_L2_MISS_LOADS/INSTR_RETIRED_ANY +L2 miss ratio = MEM_UOPS_RETIRED_L2_MISS_LOADS/(MEM_UOPS_RETIRED_L2_HIT_LOADS+MEM_UOPS_RETIRED_L2_MISS_LOADS) +- +This group measures the locality of your data accesses with regard to the +L2 cache. L2 request rate tells you how data intensive your code is +or how many data accesses you have on average per instruction. +The L2 miss rate gives a measure how often it was necessary to get +cache lines from memory. And finally L2 miss ratio tells you how many of your +memory references required a cache line to be loaded from a higher level. +While the data cache miss rate might be given by your algorithm you should +try to get data cache miss ratio as low as possible by increasing your cache +reuse. + diff --git a/collectors/likwid/groups/knl/MEM.txt b/collectors/likwid/groups/knl/MEM.txt new file mode 100644 index 0000000..0e53431 --- /dev/null +++ b/collectors/likwid/groups/knl/MEM.txt @@ -0,0 +1,47 @@ +SHORT Memory bandwidth in MBytes/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +MBOX0C0 MC_CAS_READS +MBOX0C1 MC_CAS_WRITES +MBOX1C0 MC_CAS_READS +MBOX1C1 MC_CAS_WRITES +MBOX2C0 MC_CAS_READS +MBOX2C1 MC_CAS_WRITES +MBOX4C0 MC_CAS_READS +MBOX4C1 MC_CAS_WRITES +MBOX5C0 MC_CAS_READS +MBOX5C1 MC_CAS_WRITES +MBOX6C0 MC_CAS_READS +MBOX6C1 MC_CAS_WRITES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Memory read bandwidth [MBytes/s] 1.0E-06*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX4C0+MBOX5C0+MBOX6C0)*64.0/time +Memory read data volume [GBytes] 1.0E-09*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX4C0+MBOX5C0+MBOX6C0)*64.0 +Memory writeback bandwidth [MBytes/s] 1.0E-06*(MBOX0C1+MBOX1C1+MBOX2C1+MBOX4C1+MBOX5C1+MBOX6C1)*64.0/time +Memory writeback data volume [GBytes] 1.0E-09*(MBOX0C1+MBOX1C1+MBOX2C1+MBOX4C1+MBOX5C1+MBOX6C1)*64.0 +Memory bandwidth [MBytes/s] 1.0E-06*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX4C0+MBOX5C0+MBOX6C0+MBOX0C1+MBOX1C1+MBOX2C1+MBOX4C1+MBOX5C1+MBOX6C1)*64.0/time +Memory data volume [GBytes] 1.0E-09*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX4C0+MBOX5C0+MBOX6C0+MBOX0C1+MBOX1C1+MBOX2C1+MBOX4C1+MBOX5C1+MBOX6C1)*64.0 + +LONG +Formulas: +Memory read bandwidth [MBytes/s] = 1.0E-06*(sum(MC_CAS_READS))*64/time +Memory read data volume [GBytes] = 1.0E-09*(sum(MC_CAS_READS))*64 +Memory writeback bandwidth [MBytes/s] = 1.0E-06*(sum(MC_CAS_WRITES))*64/time +Memory writeback data volume [GBytes] = 1.0E-09*(sum(MC_CAS_WRITES))*64 +Memory bandwidth [MBytes/s] = 1.0E-06*(sum(MC_CAS_READS)+sum(MC_CAS_WRITES))*64/time +Memory data volume [GBytes] = 1.0E-09*(sum(MC_CAS_READS)+sum(MC_CAS_WRITES))*64 +- +Profiling group to measure L2 to MEM load cache bandwidth. The bandwidth is computed by the +number of cache line allocated in the L2 cache. Since there is no possibility to retrieve +the evicted cache lines, this group measures only the load cache bandwidth. The +writeback metrics count only modified cache lines that are written back to go to +exclusive state +The group also output totally load and writeback data volume transferred between memory and L2. + diff --git a/collectors/likwid/groups/knl/TLB_DATA.txt b/collectors/likwid/groups/knl/TLB_DATA.txt new file mode 100644 index 0000000..5f2617f --- /dev/null +++ b/collectors/likwid/groups/knl/TLB_DATA.txt @@ -0,0 +1,27 @@ +SHORT L2 data TLB miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 PAGE_WALKS_DTLB_COUNT +PMC1 PAGE_WALKS_DTLB_CYCLES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L1 DTLB misses PMC0 +L1 DTLB miss rate PMC0/FIXC0 +L1 DTLB miss duration [Cyc] PMC1/PMC0 + +LONG +Formulas: +L1 DTLB misses = PAGE_WALKS_DTLB_COUNT +L1 DTLB miss rate = PAGE_WALKS_DTLB_COUNT / INSTR_RETIRED_ANY +L1 DTLB miss duration [Cyc] = PAGE_WALKS_DTLB_CYCLES / PAGE_WALKS_DTLB_COUNT +- +The DTLB load and store miss rates gives a measure how often a TLB miss occurred +per instruction. The duration measures the time in cycles how long a walk did take. + diff --git a/collectors/likwid/groups/knl/TLB_INSTR.txt b/collectors/likwid/groups/knl/TLB_INSTR.txt new file mode 100644 index 0000000..f3dd3ec --- /dev/null +++ b/collectors/likwid/groups/knl/TLB_INSTR.txt @@ -0,0 +1,27 @@ +SHORT L1 Instruction TLB miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 PAGE_WALKS_ITLB_COUNT +PMC1 PAGE_WALKS_ITLB_CYCLES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L1 ITLB misses PMC0 +L1 ITLB miss rate PMC0/FIXC0 +L1 ITLB miss duration [Cyc] PMC1/PMC0 + + +LONG +Formulas: +L1 ITLB misses = PAGE_WALKS_ITLB_COUNT +L1 ITLB miss rate = PAGE_WALKS_ITLB_COUNT / INSTR_RETIRED_ANY +L1 ITLB miss duration [Cyc] = PAGE_WALKS_ITLB_CYCLES / PAGE_WALKS_ITLB_COUNT +- +The ITLB miss rates gives a measure how often a TLB miss occurred +per instruction. The duration measures the time in cycles how long a walk did take. diff --git a/collectors/likwid/groups/knl/UOPS_STALLS.txt b/collectors/likwid/groups/knl/UOPS_STALLS.txt new file mode 100644 index 0000000..97cfa99 --- /dev/null +++ b/collectors/likwid/groups/knl/UOPS_STALLS.txt @@ -0,0 +1,25 @@ +SHORT UOP retirement stalls + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 UOPS_RETIRED_STALLED_CYCLES +PMC1 UOPS_RETIRED_STALLS + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Number of stalls PMC1 +Avg. stall duration [cyc] PMC0/PMC1 +Stall ratio PMC0/FIXC1 + +LONG +Formulas: +Number of stalls = UOPS_RETIRED_STALLS +Avg. stall duration [cyc] = UOPS_RETIRED_STALLED_CYCLES/UOPS_RETIRED_STALLS +Stall ratio = UOPS_RETIRED_STALLED_CYCLES/CPU_CLK_UNHALTED_CORE +- +This group measures stalls in the UOP retirement. diff --git a/collectors/likwid/groups/nehalem/BRANCH.txt b/collectors/likwid/groups/nehalem/BRANCH.txt new file mode 100644 index 0000000..1ef9f11 --- /dev/null +++ b/collectors/likwid/groups/nehalem/BRANCH.txt @@ -0,0 +1,31 @@ +SHORT Branch prediction miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 BR_INST_RETIRED_ALL_BRANCHES +PMC1 BR_MISP_RETIRED_ALL_BRANCHES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Branch rate PMC0/FIXC0 +Branch misprediction rate PMC1/FIXC0 +Branch misprediction ratio PMC1/PMC0 +Instructions per branch FIXC0/PMC0 + +LONG +Formulas: +Branch rate = BR_INST_RETIRED_ALL_BRANCHES/INSTR_RETIRED_ANY +Branch misprediction rate = BR_MISP_RETIRED_ALL_BRANCHES/INSTR_RETIRED_ANY +Branch misprediction ratio = BR_MISP_RETIRED_ALL_BRANCHES/BR_INST_RETIRED_ALL_BRANCHES +Instructions per branch = INSTR_RETIRED_ANY/BR_INST_RETIRED_ALL_BRANCHES +- +The rates state how often on average a branch or a mispredicted branch occurred +per instruction retired in total. The branch misprediction ratio sets directly +into relation what ration of all branch instruction where mispredicted. +Instructions per branch is 1/branch rate. + diff --git a/collectors/likwid/groups/nehalem/CACHE.txt b/collectors/likwid/groups/nehalem/CACHE.txt new file mode 100644 index 0000000..6603171 --- /dev/null +++ b/collectors/likwid/groups/nehalem/CACHE.txt @@ -0,0 +1,36 @@ +SHORT Data cache miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 L1D_REPL +PMC1 L1D_ALL_REF_ANY + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +data cache misses PMC0 +data cache request rate PMC1/FIXC0 +data cache miss rate PMC0/FIXC0 +data cache miss ratio PMC0/PMC1 + +LONG +Formulas: +data cache misses = L1D_REPL +data cache request rate = L1D_ALL_REF_ANY / INSTR_RETIRED_ANY +data cache miss rate = L1D_REPL / INSTR_RETIRED_ANY +data cache miss ratio = L1D_REPL / L1D_ALL_REF_ANY +- +This group measures the locality of your data accesses with regard to the +L1 cache. Data cache request rate tells you how data intensive your code is +or how many data accesses you have on average per instruction. +The data cache miss rate gives a measure how often it was necessary to get +cache lines from higher levels of the memory hierarchy. And finally +data cache miss ratio tells you how many of your memory references required +a cache line to be loaded from a higher level. While the data cache miss rate +might be given by your algorithm you should try to get data cache miss ratio +as low as possible by increasing your cache reuse. + diff --git a/collectors/likwid/groups/nehalem/DATA.txt b/collectors/likwid/groups/nehalem/DATA.txt new file mode 100644 index 0000000..31bba51 --- /dev/null +++ b/collectors/likwid/groups/nehalem/DATA.txt @@ -0,0 +1,22 @@ +SHORT Load to store ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 MEM_INST_RETIRED_LOADS +PMC1 MEM_INST_RETIRED_STORES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Load to store ratio PMC0/PMC1 + +LONG +Formulas: +Load to store ratio = MEM_INST_RETIRED_LOADS/MEM_INST_RETIRED_STORES +- +This is a simple metric to determine your load to store ratio. + diff --git a/collectors/likwid/groups/nehalem/DIVIDE.txt b/collectors/likwid/groups/nehalem/DIVIDE.txt new file mode 100644 index 0000000..6c17295 --- /dev/null +++ b/collectors/likwid/groups/nehalem/DIVIDE.txt @@ -0,0 +1,24 @@ +SHORT Divide unit information + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 ARITH_NUM_DIV +PMC1 ARITH_CYCLES_DIV_BUSY + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Number of divide ops PMC0 +Avg. divide unit usage duration PMC1/PMC0 + +LONG +Formulas: +Number of divide ops = ARITH_NUM_DIV +Avg. divide unit usage duration = ARITH_CYCLES_DIV_BUSY/ARITH_NUM_DIV +- +This performance group measures the average latency of divide operations diff --git a/collectors/likwid/groups/nehalem/FLOPS_DP.txt b/collectors/likwid/groups/nehalem/FLOPS_DP.txt new file mode 100644 index 0000000..0c2e56c --- /dev/null +++ b/collectors/likwid/groups/nehalem/FLOPS_DP.txt @@ -0,0 +1,35 @@ +SHORT Double Precision MFLOP/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 FP_COMP_OPS_EXE_SSE_FP_PACKED +PMC1 FP_COMP_OPS_EXE_SSE_FP_SCALAR +PMC2 FP_COMP_OPS_EXE_SSE_SINGLE_PRECISION +PMC3 FP_COMP_OPS_EXE_SSE_DOUBLE_PRECISION + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +DP [MFLOP/s] 1.0E-06*(PMC0*2.0+PMC1)/time +Packed [MUOPS/s] 1.0E-06*PMC0/time +Scalar [MUOPS/s] 1.0E-06*PMC1/time +SP [MUOPS/s] 1.0E-06*PMC2/time +DP [MUOPS/s] 1.0E-06*PMC3/time + +LONG +Formulas: +DP [MFLOP/s] = 1.0E-06*(FP_COMP_OPS_EXE_SSE_FP_PACKED*2+FP_COMP_OPS_EXE_SSE_FP_SCALAR)/runtime +Packed [MUOPS/s] = 1.0E-06*FP_COMP_OPS_EXE_SSE_FP_PACKED/runtime +Scalar [MUOPS/s] = 1.0E-06*FP_COMP_OPS_EXE_SSE_FP_SCALAR/runtime +SP [MUOPS/s] = 1.0E-06*FP_COMP_OPS_EXE_SSE_SINGLE_PRECISION/runtime +DP [MUOPS/s] = 1.0E-06*FP_COMP_OPS_EXE_SSE_DOUBLE_PRECISION/runtime +- +The Nehalem has no possibility to measure MFLOPs if mixed precision calculations are done. +Therefore both single as well as double precision are measured to ensure the correctness +of the measurements. You can check if your code was vectorized on the number of +FP_COMP_OPS_EXE_SSE_FP_PACKED versus the FP_COMP_OPS_EXE_SSE_FP_SCALAR. + diff --git a/collectors/likwid/groups/nehalem/FLOPS_SP.txt b/collectors/likwid/groups/nehalem/FLOPS_SP.txt new file mode 100644 index 0000000..8046cbd --- /dev/null +++ b/collectors/likwid/groups/nehalem/FLOPS_SP.txt @@ -0,0 +1,35 @@ +SHORT Single Precision MFLOP/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 FP_COMP_OPS_EXE_SSE_FP_PACKED +PMC1 FP_COMP_OPS_EXE_SSE_FP_SCALAR +PMC2 FP_COMP_OPS_EXE_SSE_SINGLE_PRECISION +PMC3 FP_COMP_OPS_EXE_SSE_DOUBLE_PRECISION + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +SP [MFLOP/s] 1.0E-06*(PMC0*4.0+PMC1)/time +Packed [MUOPS/s] 1.0E-06*PMC0/time +Scalar [MUOPS/s] 1.0E-06*PMC1/time +SP [MUOPS/s] 1.0E-06*PMC2/time +DP [MUOPS/s] 1.0E-06*PMC3/time + +LONG +Formulas: +SP [MFLOP/s] = 1.0E-06*(FP_COMP_OPS_EXE_SSE_FP_PACKED*4+FP_COMP_OPS_EXE_SSE_FP_SCALAR)/runtime +Packed [MUOPS/s] = 1.0E-06*FP_COMP_OPS_EXE_SSE_FP_PACKED/runtime +Scalar [MUOPS/s] = 1.0E-06*FP_COMP_OPS_EXE_SSE_FP_SCALAR/runtime +SP [MUOPS/s] = 1.0E-06*FP_COMP_OPS_EXE_SSE_SINGLE_PRECISION/runtime +DP [MUOPS/s] = 1.0E-06*FP_COMP_OPS_EXE_SSE_DOUBLE_PRECISION/runtime +- +The Nehalem has no possibility to measure MFLOPs if mixed precision calculations are done. +Therefore both single as well as double precision are measured to ensure the correctness +of the measurements. You can check if your code was vectorized on the number of +FP_COMP_OPS_EXE_SSE_FP_PACKED versus the FP_COMP_OPS_EXE_SSE_FP_SCALAR. + diff --git a/collectors/likwid/groups/nehalem/FLOPS_X87.txt b/collectors/likwid/groups/nehalem/FLOPS_X87.txt new file mode 100644 index 0000000..39cd8b4 --- /dev/null +++ b/collectors/likwid/groups/nehalem/FLOPS_X87.txt @@ -0,0 +1,21 @@ +SHORT X87 MFLOP/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 INST_RETIRED_X87 + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +X87 [MFLOP/s] 1.0E-06*PMC0/time + +LONG +Formulas: +X87 [MFLOP/s] = 1.0E-06*INST_RETIRED_X87/runtime +- +Profiling group to measure X87 FLOP rate. + diff --git a/collectors/likwid/groups/nehalem/ICACHE.txt b/collectors/likwid/groups/nehalem/ICACHE.txt new file mode 100644 index 0000000..49943ff --- /dev/null +++ b/collectors/likwid/groups/nehalem/ICACHE.txt @@ -0,0 +1,25 @@ +SHORT Instruction cache miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 L1I_READS +PMC1 L1I_MISSES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L1I request rate PMC0/FIXC0 +L1I miss rate PMC1/FIXC0 +L1I miss ratio PMC1/PMC0 + +LONG +Formulas: +L1I request rate = L1I_READS / INSTR_RETIRED_ANY +L1I miss rate = ICACHE_MISSES / INSTR_RETIRED_ANY +L1I miss ratio = ICACHE_MISSES / L1I_READS +- +This group measures some L1 instruction cache metrics. diff --git a/collectors/likwid/groups/nehalem/L2.txt b/collectors/likwid/groups/nehalem/L2.txt new file mode 100644 index 0000000..e2715cc --- /dev/null +++ b/collectors/likwid/groups/nehalem/L2.txt @@ -0,0 +1,40 @@ +SHORT L2 cache bandwidth in MBytes/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 L1D_REPL +PMC1 L1D_M_EVICT +PMC2 L1I_MISSES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L2D load bandwidth [MBytes/s] 1.0E-06*PMC0*64.0/time +L2D load data volume [GBytes] 1.0E-09*PMC0*64.0 +L2D evict bandwidth [MBytes/s] 1.0E-06*PMC1*64.0/time +L2D evict data volume [GBytes] 1.0E-09*PMC1*64.0 +L2 bandwidth [MBytes/s] 1.0E-06*(PMC0+PMC1+PMC2)*64.0/time +L2 data volume [GBytes] 1.0E-09*(PMC0+PMC1+PMC2)*64.0 + +LONG +Formulas: +L2D load bandwidth [MBytes/s] = 1.0E-06*L1D_REPL*64.0/time +L2D load data volume [GBytes] = 1.0E-09*L1D_REPL*64.0 +L2D evict bandwidth [MBytes/s] = 1.0E-06*L1D_M_EVICT*64.0/time +L2D evict data volume [GBytes] = 1.0E-09*L1D_M_EVICT*64.0 +L2 bandwidth [MBytes/s] = 1.0E-06*(L1D_REPL+L1D_M_EVICT+L1I_MISSES)*64/time +L2 data volume [GBytes] = 1.0E-09*(L1D_REPL+L1D_M_EVICT+L1I_MISSES)*64 +- +Profiling group to measure L2 cache bandwidth. The bandwidth is +computed by the number of cache line allocated in the L1 and the +number of modified cache lines evicted from the L1. Also reports on +total data volume transferred between L2 and L1 cache. +Note that this bandwidth also includes data transfers due to a +write allocate load on a store miss in L1 and traffic caused by misses in the +L1 instruction cache. + + diff --git a/collectors/likwid/groups/nehalem/L2CACHE.txt b/collectors/likwid/groups/nehalem/L2CACHE.txt new file mode 100644 index 0000000..343b263 --- /dev/null +++ b/collectors/likwid/groups/nehalem/L2CACHE.txt @@ -0,0 +1,34 @@ +SHORT L2 cache miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 L2_RQSTS_REFERENCES +PMC1 L2_RQSTS_MISS + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L2 request rate PMC0/FIXC0 +L2 miss rate PMC1/FIXC0 +L2 miss ratio PMC1/PMC0 + +LONG +Formulas: +L2 request rate = L2_RQSTS_REFERENCES/INSTR_RETIRED_ANY +L2 miss rate = L2_RQSTS_MISS/INSTR_RETIRED_ANY +L2 miss ratio = L2_RQSTS_MISS/L2_RQSTS_REFERENCES +- +This group measures the locality of your data accesses with regard to the +L2 cache. L2 request rate tells you how data intensive your code is +or how many data accesses you have on average per instruction. +The L2 miss rate gives a measure how often it was necessary to get +cache lines from memory. And finally L2 miss ratio tells you how many of your +memory references required a cache line to be loaded from a higher level. +While the data cache miss rate might be given by your algorithm you should +try to get data cache miss ratio as low as possible by increasing your cache reuse. + + diff --git a/collectors/likwid/groups/nehalem/L3.txt b/collectors/likwid/groups/nehalem/L3.txt new file mode 100644 index 0000000..70b5f29 --- /dev/null +++ b/collectors/likwid/groups/nehalem/L3.txt @@ -0,0 +1,36 @@ +SHORT L3 cache bandwidth in MBytes/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 L2_LINES_IN_ANY +PMC1 L2_LINES_OUT_DEMAND_DIRTY + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L3 load bandwidth [MBytes/s] 1.0E-06*PMC0*64.0/time +L3 load data volume [GBytes] 1.0E-09*PMC0*64.0 +L3 evict bandwidth [MBytes/s] 1.0E-06*PMC1*64.0/time +L3 evict data volume [GBytes] 1.0E-09*PMC1*64.0 +L3 bandwidth [MBytes/s] 1.0E-06*(PMC0+PMC1)*64.0/time +L3 data volume [GBytes] 1.0E-09*(PMC0+PMC1)*64.0 + +LONG +Formulas: +L3 load bandwidth [MBytes/s] = 1.0E-06*L2_LINES_IN_ANY*64.0/time +L3 load data volume [GBytes] = 1.0E-09*L2_LINES_IN_ANY*64.0 +L3 evict bandwidth [MBytes/s] = 1.0E-06*L2_LINES_OUT_DEMAND_DIRTY*64.0/time +L3 evict data volume [GBytes] = 1.0E-09*L2_LINES_OUT_DEMAND_DIRTY*64.0 +L3 bandwidth [MBytes/s] = 1.0E-06*(L2_LINES_IN_ANY+L2_LINES_OUT_DEMAND_DIRTY)*64/time +L3 data volume [GBytes] = 1.0E-09*(L2_LINES_IN_ANY+L2_LINES_OUT_DEMAND_DIRTY)*64 +- +Profiling group to measure L3 cache bandwidth. The bandwidth is computed by the +number of cache line allocated in the L2 and the number of modified cache lines +evicted from the L2. Also reports total data volume between L3 and L2 caches. +Note that this bandwidth also includes data transfers due to a write allocate +load on a store miss in L2. + diff --git a/collectors/likwid/groups/nehalem/L3CACHE.txt b/collectors/likwid/groups/nehalem/L3CACHE.txt new file mode 100644 index 0000000..15e00ed --- /dev/null +++ b/collectors/likwid/groups/nehalem/L3CACHE.txt @@ -0,0 +1,34 @@ +SHORT L3 cache miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +UPMC0 UNC_L3_HITS_ANY +UPMC1 UNC_L3_MISS_ANY + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L3 request rate (UPMC0+UPMC1)/FIXC0 +L3 miss rate UPMC1/FIXC0 +L3 miss ratio UPMC1/(UPMC0+UPMC1) + +LONG +Formulas: +L3 request rate = (UNC_L3_HITS_ANY+UNC_L3_MISS_ANY)/INSTR_RETIRED_ANY +L3 miss rate = UNC_L3_MISS_ANY/INSTR_RETIRED_ANY +L3 miss ratio = UNC_L3_MISS_ANY/(UNC_L3_HITS_ANY+UNC_L3_MISS_ANY) +- +This group measures the locality of your data accesses with regard to the +L3 cache. L3 request rate tells you how data intensive your code is +or how many data accesses you have on average per instruction. +The L3 miss rate gives a measure how often it was necessary to get +cache lines from memory. And finally L3 miss ratio tells you how many of your +memory references required a cache line to be loaded from a higher level. +While the data cache miss rate might be given by your algorithm you should +try to get data cache miss ratio as low as possible by increasing your cache reuse. + + diff --git a/collectors/likwid/groups/nehalem/MEM.txt b/collectors/likwid/groups/nehalem/MEM.txt new file mode 100644 index 0000000..b528670 --- /dev/null +++ b/collectors/likwid/groups/nehalem/MEM.txt @@ -0,0 +1,49 @@ +SHORT Main memory bandwidth in MBytes/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +UPMC0 UNC_QMC_NORMAL_READS_ANY +UPMC1 UNC_QMC_WRITES_FULL_ANY +UPMC2 UNC_QHL_REQUESTS_REMOTE_READS +UPMC3 UNC_QHL_REQUESTS_REMOTE_WRITES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Memory read bandwidth [MBytes/s] 1.0E-06*UPMC0*64.0/time +Memory read data volume [GBytes] 1.0E-09*UPMC0*64.0 +Memory write bandwidth [MBytes/s] 1.0E-06*UPMC1*64.0/time +Memory write data volume [GBytes] 1.0E-09*UPMC1*64.0 +Memory bandwidth [MBytes/s] 1.0E-06*(UPMC0+UPMC1)*64.0/time +Memory data volume [GBytes] 1.0E-09*(UPMC0+UPMC1)*64.0 +Remote memory read bandwidth [MBytes/s] 1.0E-06*UPMC2*64.0/time +Remote memory read data volume [GBytes] 1.0E-09*UPMC2*64.0 +Remote memory write bandwidth [MBytes/s] 1.0E-06*UPMC3*64.0/time +Remote memory write data volume [GBytes] 1.0E-09*UPMC3*64.0 +Remote memory bandwidth [MBytes/s] 1.0E-06*(UPMC2+UPMC3)*64.0/time +Remote memory data volume [GBytes] 1.0E-09*(UPMC2+UPMC3)*64.0 + +LONG +Formulas: +Memory read bandwidth [MBytes/s] = 1.0E-06*UNC_QMC_NORMAL_READS_ANY*64.0/time +Memory read data volume [GBytes] = 1.0E-09*UNC_QMC_NORMAL_READS_ANY*64.0 +Memory write bandwidth [MBytes/s] = 1.0E-06*UNC_QMC_WRITES_FULL_ANY*64.0/time +Memory write data volume [GBytes] = 1.0E-09*UNC_QMC_WRITES_FULL_ANY*64.0 +Memory bandwidth [MBytes/s] = 1.0E-06*(UNC_QMC_NORMAL_READS_ANY+UNC_QMC_WRITES_FULL_ANY)*64.0/time +Memory data volume [GBytes] = 1.0E-09*(UNC_QMC_NORMAL_READS_ANY+UNC_QMC_WRITES_FULL_ANY)*64.0 +Remote memory read bandwidth [MBytes/s] = 1.0E-06*UNC_QHL_REQUESTS_REMOTE_READS*64.0/time +Remote memory read data volume [GBytes] = 1.0E-09*UNC_QHL_REQUESTS_REMOTE_READS*64.0 +Remote memory write bandwidth [MBytes/s] = 1.0E-06*UNC_QHL_REQUESTS_REMOTE_WRITES*64.0/time +Remote memory write data volume [GBytes] = 1.0E-09*UNC_QHL_REQUESTS_REMOTE_WRITES*64.0 +Remote memory bandwidth [MBytes/s] = 1.0E-06*(UNC_QHL_REQUESTS_REMOTE_READS+UNC_QHL_REQUESTS_REMOTE_WRITES)*64.0/time +Remote memory data volume [GBytes] = 1.0E-09*(UNC_QHL_REQUESTS_REMOTE_READS+UNC_QHL_REQUESTS_REMOTE_WRITES)*64.0 +- +Profiling group to measure memory bandwidth drawn by all cores of a socket. +This group will be measured by one core per socket. The Remote Read BW tells +you if cache lines are transferred between sockets, meaning that cores access +data owned by a remote NUMA domain. + diff --git a/collectors/likwid/groups/nehalem/SCHEDULER.txt b/collectors/likwid/groups/nehalem/SCHEDULER.txt new file mode 100644 index 0000000..0e43cce --- /dev/null +++ b/collectors/likwid/groups/nehalem/SCHEDULER.txt @@ -0,0 +1,25 @@ +SHORT Scheduler Ports + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 UOPS_EXECUTED_PORT0 +PMC1 UOPS_EXECUTED_PORT1 +PMC2 UOPS_EXECUTED_PORT5 + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Ratio Port 1 PMC1/PMC0 +Ratio Port 5 PMC2/PMC0 + +LONG +Formulas: +Ratio Port 1 = UOPS_EXECUTED_PORT1/UOPS_EXECUTED_PORT0 +Ratio Port 5 = UOPS_EXECUTED_PORT5/UOPS_EXECUTED_PORT0 +- +Measures how many instructions were scheduled on which issue port. + diff --git a/collectors/likwid/groups/nehalem/TLB.txt b/collectors/likwid/groups/nehalem/TLB.txt new file mode 100644 index 0000000..c380851 --- /dev/null +++ b/collectors/likwid/groups/nehalem/TLB.txt @@ -0,0 +1,30 @@ +SHORT TLB miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 DTLB_MISSES_ANY +PMC1 L1D_ALL_REF_ANY + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L1 DTLB request rate PMC1/FIXC0 +L1 DTLB miss rate PMC0/FIXC0 +L1 DTLB miss ratio PMC0/PMC1 + +LONG +Formulas: +L1 DTLB request rate = L1D_ALL_REF_ANY / INSTR_RETIRED_ANY +DTLB miss rate = DTLB_MISSES_ANY / INSTR_RETIRED_ANY +L1 DTLB miss ratio = DTLB_MISSES_ANY / L1D_ALL_REF_ANY +- +L1 DTLB request rate tells you how data intensive your code is +or how many data accesses you have on average per instruction. +The DTLB miss rate gives a measure how often a TLB miss occurred +per instruction. And finally L1 DTLB miss ratio tells you how many +of your memory references required caused a TLB miss on average. + diff --git a/collectors/likwid/groups/nehalemEX/BRANCH.txt b/collectors/likwid/groups/nehalemEX/BRANCH.txt new file mode 100644 index 0000000..1ef9f11 --- /dev/null +++ b/collectors/likwid/groups/nehalemEX/BRANCH.txt @@ -0,0 +1,31 @@ +SHORT Branch prediction miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 BR_INST_RETIRED_ALL_BRANCHES +PMC1 BR_MISP_RETIRED_ALL_BRANCHES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Branch rate PMC0/FIXC0 +Branch misprediction rate PMC1/FIXC0 +Branch misprediction ratio PMC1/PMC0 +Instructions per branch FIXC0/PMC0 + +LONG +Formulas: +Branch rate = BR_INST_RETIRED_ALL_BRANCHES/INSTR_RETIRED_ANY +Branch misprediction rate = BR_MISP_RETIRED_ALL_BRANCHES/INSTR_RETIRED_ANY +Branch misprediction ratio = BR_MISP_RETIRED_ALL_BRANCHES/BR_INST_RETIRED_ALL_BRANCHES +Instructions per branch = INSTR_RETIRED_ANY/BR_INST_RETIRED_ALL_BRANCHES +- +The rates state how often on average a branch or a mispredicted branch occurred +per instruction retired in total. The branch misprediction ratio sets directly +into relation what ration of all branch instruction where mispredicted. +Instructions per branch is 1/branch rate. + diff --git a/collectors/likwid/groups/nehalemEX/CACHE.txt b/collectors/likwid/groups/nehalemEX/CACHE.txt new file mode 100644 index 0000000..6603171 --- /dev/null +++ b/collectors/likwid/groups/nehalemEX/CACHE.txt @@ -0,0 +1,36 @@ +SHORT Data cache miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 L1D_REPL +PMC1 L1D_ALL_REF_ANY + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +data cache misses PMC0 +data cache request rate PMC1/FIXC0 +data cache miss rate PMC0/FIXC0 +data cache miss ratio PMC0/PMC1 + +LONG +Formulas: +data cache misses = L1D_REPL +data cache request rate = L1D_ALL_REF_ANY / INSTR_RETIRED_ANY +data cache miss rate = L1D_REPL / INSTR_RETIRED_ANY +data cache miss ratio = L1D_REPL / L1D_ALL_REF_ANY +- +This group measures the locality of your data accesses with regard to the +L1 cache. Data cache request rate tells you how data intensive your code is +or how many data accesses you have on average per instruction. +The data cache miss rate gives a measure how often it was necessary to get +cache lines from higher levels of the memory hierarchy. And finally +data cache miss ratio tells you how many of your memory references required +a cache line to be loaded from a higher level. While the data cache miss rate +might be given by your algorithm you should try to get data cache miss ratio +as low as possible by increasing your cache reuse. + diff --git a/collectors/likwid/groups/nehalemEX/DATA.txt b/collectors/likwid/groups/nehalemEX/DATA.txt new file mode 100644 index 0000000..31bba51 --- /dev/null +++ b/collectors/likwid/groups/nehalemEX/DATA.txt @@ -0,0 +1,22 @@ +SHORT Load to store ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 MEM_INST_RETIRED_LOADS +PMC1 MEM_INST_RETIRED_STORES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Load to store ratio PMC0/PMC1 + +LONG +Formulas: +Load to store ratio = MEM_INST_RETIRED_LOADS/MEM_INST_RETIRED_STORES +- +This is a simple metric to determine your load to store ratio. + diff --git a/collectors/likwid/groups/nehalemEX/DIVIDE.txt b/collectors/likwid/groups/nehalemEX/DIVIDE.txt new file mode 100644 index 0000000..cb15563 --- /dev/null +++ b/collectors/likwid/groups/nehalemEX/DIVIDE.txt @@ -0,0 +1,24 @@ +SHORT Divide unit information + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0:EDGEDETECT ARITH_CYCLES_DIV_BUSY +PMC1 ARITH_CYCLES_DIV_BUSY + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Number of divide ops PMC0:EDGEDETECT +Avg. divide unit usage duration PMC1/PMC0:EDGEDETECT + +LONG +Formulas: +Number of divide ops = ARITH_CYCLES_DIV_BUSY:EDGEDETECT +Avg. divide unit usage duration = ARITH_CYCLES_DIV_BUSY/ARITH_CYCLES_DIV_BUSY:EDGEDETECT +- +This performance group measures the average latency of divide operations diff --git a/collectors/likwid/groups/nehalemEX/FLOPS_DP.txt b/collectors/likwid/groups/nehalemEX/FLOPS_DP.txt new file mode 100644 index 0000000..0c2e56c --- /dev/null +++ b/collectors/likwid/groups/nehalemEX/FLOPS_DP.txt @@ -0,0 +1,35 @@ +SHORT Double Precision MFLOP/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 FP_COMP_OPS_EXE_SSE_FP_PACKED +PMC1 FP_COMP_OPS_EXE_SSE_FP_SCALAR +PMC2 FP_COMP_OPS_EXE_SSE_SINGLE_PRECISION +PMC3 FP_COMP_OPS_EXE_SSE_DOUBLE_PRECISION + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +DP [MFLOP/s] 1.0E-06*(PMC0*2.0+PMC1)/time +Packed [MUOPS/s] 1.0E-06*PMC0/time +Scalar [MUOPS/s] 1.0E-06*PMC1/time +SP [MUOPS/s] 1.0E-06*PMC2/time +DP [MUOPS/s] 1.0E-06*PMC3/time + +LONG +Formulas: +DP [MFLOP/s] = 1.0E-06*(FP_COMP_OPS_EXE_SSE_FP_PACKED*2+FP_COMP_OPS_EXE_SSE_FP_SCALAR)/runtime +Packed [MUOPS/s] = 1.0E-06*FP_COMP_OPS_EXE_SSE_FP_PACKED/runtime +Scalar [MUOPS/s] = 1.0E-06*FP_COMP_OPS_EXE_SSE_FP_SCALAR/runtime +SP [MUOPS/s] = 1.0E-06*FP_COMP_OPS_EXE_SSE_SINGLE_PRECISION/runtime +DP [MUOPS/s] = 1.0E-06*FP_COMP_OPS_EXE_SSE_DOUBLE_PRECISION/runtime +- +The Nehalem has no possibility to measure MFLOPs if mixed precision calculations are done. +Therefore both single as well as double precision are measured to ensure the correctness +of the measurements. You can check if your code was vectorized on the number of +FP_COMP_OPS_EXE_SSE_FP_PACKED versus the FP_COMP_OPS_EXE_SSE_FP_SCALAR. + diff --git a/collectors/likwid/groups/nehalemEX/FLOPS_SP.txt b/collectors/likwid/groups/nehalemEX/FLOPS_SP.txt new file mode 100644 index 0000000..8046cbd --- /dev/null +++ b/collectors/likwid/groups/nehalemEX/FLOPS_SP.txt @@ -0,0 +1,35 @@ +SHORT Single Precision MFLOP/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 FP_COMP_OPS_EXE_SSE_FP_PACKED +PMC1 FP_COMP_OPS_EXE_SSE_FP_SCALAR +PMC2 FP_COMP_OPS_EXE_SSE_SINGLE_PRECISION +PMC3 FP_COMP_OPS_EXE_SSE_DOUBLE_PRECISION + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +SP [MFLOP/s] 1.0E-06*(PMC0*4.0+PMC1)/time +Packed [MUOPS/s] 1.0E-06*PMC0/time +Scalar [MUOPS/s] 1.0E-06*PMC1/time +SP [MUOPS/s] 1.0E-06*PMC2/time +DP [MUOPS/s] 1.0E-06*PMC3/time + +LONG +Formulas: +SP [MFLOP/s] = 1.0E-06*(FP_COMP_OPS_EXE_SSE_FP_PACKED*4+FP_COMP_OPS_EXE_SSE_FP_SCALAR)/runtime +Packed [MUOPS/s] = 1.0E-06*FP_COMP_OPS_EXE_SSE_FP_PACKED/runtime +Scalar [MUOPS/s] = 1.0E-06*FP_COMP_OPS_EXE_SSE_FP_SCALAR/runtime +SP [MUOPS/s] = 1.0E-06*FP_COMP_OPS_EXE_SSE_SINGLE_PRECISION/runtime +DP [MUOPS/s] = 1.0E-06*FP_COMP_OPS_EXE_SSE_DOUBLE_PRECISION/runtime +- +The Nehalem has no possibility to measure MFLOPs if mixed precision calculations are done. +Therefore both single as well as double precision are measured to ensure the correctness +of the measurements. You can check if your code was vectorized on the number of +FP_COMP_OPS_EXE_SSE_FP_PACKED versus the FP_COMP_OPS_EXE_SSE_FP_SCALAR. + diff --git a/collectors/likwid/groups/nehalemEX/FLOPS_X87.txt b/collectors/likwid/groups/nehalemEX/FLOPS_X87.txt new file mode 100644 index 0000000..39cd8b4 --- /dev/null +++ b/collectors/likwid/groups/nehalemEX/FLOPS_X87.txt @@ -0,0 +1,21 @@ +SHORT X87 MFLOP/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 INST_RETIRED_X87 + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +X87 [MFLOP/s] 1.0E-06*PMC0/time + +LONG +Formulas: +X87 [MFLOP/s] = 1.0E-06*INST_RETIRED_X87/runtime +- +Profiling group to measure X87 FLOP rate. + diff --git a/collectors/likwid/groups/nehalemEX/ICACHE.txt b/collectors/likwid/groups/nehalemEX/ICACHE.txt new file mode 100644 index 0000000..49943ff --- /dev/null +++ b/collectors/likwid/groups/nehalemEX/ICACHE.txt @@ -0,0 +1,25 @@ +SHORT Instruction cache miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 L1I_READS +PMC1 L1I_MISSES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L1I request rate PMC0/FIXC0 +L1I miss rate PMC1/FIXC0 +L1I miss ratio PMC1/PMC0 + +LONG +Formulas: +L1I request rate = L1I_READS / INSTR_RETIRED_ANY +L1I miss rate = ICACHE_MISSES / INSTR_RETIRED_ANY +L1I miss ratio = ICACHE_MISSES / L1I_READS +- +This group measures some L1 instruction cache metrics. diff --git a/collectors/likwid/groups/nehalemEX/L2.txt b/collectors/likwid/groups/nehalemEX/L2.txt new file mode 100644 index 0000000..e2715cc --- /dev/null +++ b/collectors/likwid/groups/nehalemEX/L2.txt @@ -0,0 +1,40 @@ +SHORT L2 cache bandwidth in MBytes/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 L1D_REPL +PMC1 L1D_M_EVICT +PMC2 L1I_MISSES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L2D load bandwidth [MBytes/s] 1.0E-06*PMC0*64.0/time +L2D load data volume [GBytes] 1.0E-09*PMC0*64.0 +L2D evict bandwidth [MBytes/s] 1.0E-06*PMC1*64.0/time +L2D evict data volume [GBytes] 1.0E-09*PMC1*64.0 +L2 bandwidth [MBytes/s] 1.0E-06*(PMC0+PMC1+PMC2)*64.0/time +L2 data volume [GBytes] 1.0E-09*(PMC0+PMC1+PMC2)*64.0 + +LONG +Formulas: +L2D load bandwidth [MBytes/s] = 1.0E-06*L1D_REPL*64.0/time +L2D load data volume [GBytes] = 1.0E-09*L1D_REPL*64.0 +L2D evict bandwidth [MBytes/s] = 1.0E-06*L1D_M_EVICT*64.0/time +L2D evict data volume [GBytes] = 1.0E-09*L1D_M_EVICT*64.0 +L2 bandwidth [MBytes/s] = 1.0E-06*(L1D_REPL+L1D_M_EVICT+L1I_MISSES)*64/time +L2 data volume [GBytes] = 1.0E-09*(L1D_REPL+L1D_M_EVICT+L1I_MISSES)*64 +- +Profiling group to measure L2 cache bandwidth. The bandwidth is +computed by the number of cache line allocated in the L1 and the +number of modified cache lines evicted from the L1. Also reports on +total data volume transferred between L2 and L1 cache. +Note that this bandwidth also includes data transfers due to a +write allocate load on a store miss in L1 and traffic caused by misses in the +L1 instruction cache. + + diff --git a/collectors/likwid/groups/nehalemEX/L2CACHE.txt b/collectors/likwid/groups/nehalemEX/L2CACHE.txt new file mode 100644 index 0000000..343b263 --- /dev/null +++ b/collectors/likwid/groups/nehalemEX/L2CACHE.txt @@ -0,0 +1,34 @@ +SHORT L2 cache miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 L2_RQSTS_REFERENCES +PMC1 L2_RQSTS_MISS + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L2 request rate PMC0/FIXC0 +L2 miss rate PMC1/FIXC0 +L2 miss ratio PMC1/PMC0 + +LONG +Formulas: +L2 request rate = L2_RQSTS_REFERENCES/INSTR_RETIRED_ANY +L2 miss rate = L2_RQSTS_MISS/INSTR_RETIRED_ANY +L2 miss ratio = L2_RQSTS_MISS/L2_RQSTS_REFERENCES +- +This group measures the locality of your data accesses with regard to the +L2 cache. L2 request rate tells you how data intensive your code is +or how many data accesses you have on average per instruction. +The L2 miss rate gives a measure how often it was necessary to get +cache lines from memory. And finally L2 miss ratio tells you how many of your +memory references required a cache line to be loaded from a higher level. +While the data cache miss rate might be given by your algorithm you should +try to get data cache miss ratio as low as possible by increasing your cache reuse. + + diff --git a/collectors/likwid/groups/nehalemEX/L3.txt b/collectors/likwid/groups/nehalemEX/L3.txt new file mode 100644 index 0000000..51a0811 --- /dev/null +++ b/collectors/likwid/groups/nehalemEX/L3.txt @@ -0,0 +1,37 @@ +SHORT L3 cache bandwidth in MBytes/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 L2_LINES_IN_ANY +PMC1 L2_LINES_OUT_DEMAND_DIRTY +PMC2 L2_LINES_OUT_PREFETCH_DIRTY + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L3 load bandwidth [MBytes/s] 1.0E-06*PMC0*64.0/time +L3 load data volume [GBytes] 1.0E-09*PMC0*64.0 +L3 evict bandwidth [MBytes/s] 1.0E-06*(PMC1+PMC2)*64.0/time +L3 evict data volume [GBytes] 1.0E-09*(PMC1+PMC2)*64.0 +L3 bandwidth [MBytes/s] 1.0E-06*(PMC0+PMC1+PMC2)*64.0/time +L3 data volume [GBytes] 1.0E-09*(PMC0+PMC1+PMC2)*64.0 + +LONG +Formulas: +L3 load bandwidth [MBytes/s] = 1.0E-06*L2_LINES_IN_ANY*64.0/time +L3 load data volume [GBytes] = 1.0E-09*L2_LINES_IN_ANY*64.0 +L3 evict bandwidth [MBytes/s] = 1.0E-06*(L2_LINES_OUT_DEMAND_DIRTY+L2_LINES_OUT_PREFETCH_DIRTY)*64.0/time +L3 evict data volume [GBytes] = 1.0E-09*(L2_LINES_OUT_DEMAND_DIRTY+L2_LINES_OUT_PREFETCH_DIRTY)*64.0 +L3 bandwidth [MBytes/s] = 1.0E-06*(L2_LINES_IN_ANY+L2_LINES_OUT_DEMAND_DIRTY+L2_LINES_OUT_PREFETCH_DIRTY)*64/time +L3 data volume [GBytes] = 1.0E-09*(L2_LINES_IN_ANY+L2_LINES_OUT_DEMAND_DIRTY+L2_LINES_OUT_PREFETCH_DIRTY)*64 +- +Profiling group to measure L3 cache bandwidth. The bandwidth is computed by the +number of cache line allocated in the L2 and the number of modified cache lines +evicted from the L2. Also reports total data volume between L3 and L2 caches. +Note that this bandwidth also includes data transfers due to a write allocate +load on a store miss in L2. + diff --git a/collectors/likwid/groups/nehalemEX/L3CACHE.txt b/collectors/likwid/groups/nehalemEX/L3CACHE.txt new file mode 100644 index 0000000..c6b204e --- /dev/null +++ b/collectors/likwid/groups/nehalemEX/L3CACHE.txt @@ -0,0 +1,48 @@ +SHORT L3 cache miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +CBOX0C0 LLC_HITS_ALL +CBOX0C1 LLC_MISSES_ALL +CBOX1C0 LLC_HITS_ALL +CBOX1C1 LLC_MISSES_ALL +CBOX2C0 LLC_HITS_ALL +CBOX2C1 LLC_MISSES_ALL +CBOX3C0 LLC_HITS_ALL +CBOX3C1 LLC_MISSES_ALL +CBOX4C0 LLC_HITS_ALL +CBOX4C1 LLC_MISSES_ALL +CBOX5C0 LLC_HITS_ALL +CBOX5C1 LLC_MISSES_ALL +CBOX6C0 LLC_HITS_ALL +CBOX6C1 LLC_MISSES_ALL +CBOX7C0 LLC_HITS_ALL +CBOX7C1 LLC_MISSES_ALL + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L3 request rate (CBOX0C0+CBOX0C1+CBOX1C0+CBOX1C1+CBOX2C0+CBOX2C1+CBOX3C0+CBOX3C1+CBOX4C0+CBOX4C1+CBOX5C0+CBOX5C1+CBOX6C0+CBOX6C1+CBOX7C0+CBOX7C1)/FIXC0 +L3 miss rate (CBOX0C1+CBOX1C1+CBOX2C1+CBOX3C1+CBOX4C1+CBOX5C1+CBOX6C1+CBOX7C1)/FIXC0 +L3 miss ratio (CBOX0C1+CBOX1C1+CBOX2C1+CBOX3C1+CBOX4C1+CBOX5C1+CBOX6C1+CBOX7C1)/(CBOX0C0+CBOX0C1+CBOX1C0+CBOX1C1+CBOX2C0+CBOX2C1+CBOX3C0+CBOX3C1+CBOX4C0+CBOX4C1+CBOX5C0+CBOX5C1+CBOX6C0+CBOX6C1+CBOX7C0+CBOX7C1) + +LONG +Formulas: +L3 request rate = (SUM(LLC_HITS_ALL)+SUM(LLC_MISSES_ALL))/INSTR_RETIRED_ANY +L3 miss rate = SUM(LLC_MISSES_ALL)/INSTR_RETIRED_ANY +L3 miss ratio = SUM(LLC_MISSES_ALL)/(SUM(LLC_HITS_ALL)+SUM(LLC_MISSES_ALL)) +- +This group measures the locality of your data accesses with regard to the +L3 cache. L3 request rate tells you how data intensive your code is +or how many data accesses you have on average per instruction. +The L3 miss rate gives a measure how often it was necessary to get +cache lines from memory. And finally L3 miss ratio tells you how many of your +memory references required a cache line to be loaded from a higher level. +While the data cache miss rate might be given by your algorithm you should +try to get data cache miss ratio as low as possible by increasing your cache reuse. + + diff --git a/collectors/likwid/groups/nehalemEX/MEM.txt b/collectors/likwid/groups/nehalemEX/MEM.txt new file mode 100644 index 0000000..d3d2522 --- /dev/null +++ b/collectors/likwid/groups/nehalemEX/MEM.txt @@ -0,0 +1,43 @@ +SHORT Main memory bandwidth + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +WBOXFIX UNCORE_CLOCK +MBOX0C0 FVC_EV0_BBOX_CMDS_READS +MBOX0C1 DRAM_CMD_CAS_WR_OPN +MBOX1C0 FVC_EV0_BBOX_CMDS_READS +MBOX1C1 DRAM_CMD_CAS_WR_OPN + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +Uncore Clock [MHz] 1.E-06*(WBOXFIX)/time +CPI FIXC1/FIXC0 +Memory read bandwidth [MBytes/s] 1.0E-06*(MBOX0C0+MBOX1C0)*64.0/time +Memory read data volume [GBytes] 1.0E-09*(MBOX0C0+MBOX1C0)*64.0 +Memory write bandwidth [MBytes/s] 1.0E-06*(MBOX0C1+MBOX1C1)*64.0/time +Memory write data volume [GBytes] 1.0E-09*(MBOX0C1+MBOX1C1)*64.0 +Memory bandwidth [MBytes/s] 1.0E-06*(MBOX0C0+MBOX1C0+MBOX0C1+MBOX1C1)*64/time +Memory data volume [GBytes] 1.0E-09*(MBOX0C0+MBOX1C0+MBOX0C1+MBOX1C1)*64 + +LONG +Formulas: +Uncore Clock [MHz] = 1.E-06*(UNCORE_CLOCK)/time +Memory read bandwidth [MBytes/s] = 1.0E-06*(SUM(FVC_EV0_BBOX_CMDS_READS))*64.0/time +Memory read data volume [GBytes] = 1.0E-09*(SUM(FVC_EV0_BBOX_CMDS_READS))*64.0 +Memory write bandwidth [MBytes/s] = 1.0E-06*(SUM(MDRAM_CMD_CAS_WR_OPN))*64.0/time +Memory write data volume [GBytes] = 1.0E-09*(SUM(DRAM_CMD_CAS_WR_OPN))*64.0 +Memory bandwidth [MBytes/s] = 1.0E-06*(SUM(FVC_EV0_BBOX_CMDS_READS)+SUM(DRAM_CMD_CAS_WR_OPN))*64.0/time +Memory data volume [GBytes] = 1.0E-09*(SUM(FVC_EV0_BBOX_CMDS_READS)+SUM(DRAM_CMD_CAS_WR_OPN))*64.0 +- +Profiling group to measure memory bandwidth drawn by all cores of a socket. +On Nehalem EX it is not possible to measure the write operations with the +FVC_EV0_BBOX_CMDS_WRITES event at the same time as the FVC_EV0_BBOX_CMDS_READS +because they set contrary bits. The DRAM_CMD_CAS_WR_OPN is an alternative but +it only measures write operations to open pages, hence writes to closed pages +are not included here. + diff --git a/collectors/likwid/groups/nehalemEX/SCHEDULER.txt b/collectors/likwid/groups/nehalemEX/SCHEDULER.txt new file mode 100644 index 0000000..0e43cce --- /dev/null +++ b/collectors/likwid/groups/nehalemEX/SCHEDULER.txt @@ -0,0 +1,25 @@ +SHORT Scheduler Ports + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 UOPS_EXECUTED_PORT0 +PMC1 UOPS_EXECUTED_PORT1 +PMC2 UOPS_EXECUTED_PORT5 + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Ratio Port 1 PMC1/PMC0 +Ratio Port 5 PMC2/PMC0 + +LONG +Formulas: +Ratio Port 1 = UOPS_EXECUTED_PORT1/UOPS_EXECUTED_PORT0 +Ratio Port 5 = UOPS_EXECUTED_PORT5/UOPS_EXECUTED_PORT0 +- +Measures how many instructions were scheduled on which issue port. + diff --git a/collectors/likwid/groups/nehalemEX/TLB.txt b/collectors/likwid/groups/nehalemEX/TLB.txt new file mode 100644 index 0000000..0e358b8 --- /dev/null +++ b/collectors/likwid/groups/nehalemEX/TLB.txt @@ -0,0 +1,30 @@ +SHORT TLB miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 DTLB_MISSES_ANY +PMC1 L1D_ALL_REF_ANY + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L1 DTLB request rate PMC1/FIXC0 +L1 DTLB miss rate PMC0/FIXC0 +L1 DTLB miss ratio PMC0/PMC1 + +LONG +Formulas: +L1 DTLB request rate = L1D_ALL_REF_ANY / INSTR_RETIRED_ANY +DTLB miss rate = DTLB_MISSES_ANY / INSTR_RETIRED_ANY +L1 DTLB miss ratio = DTLB_MISSES_ANY / L1D_ALL_REF_ANY +- +L1 DTLB request rate tells you how data intensive your code is +or how many data accesses you have on average per instruction. +The DTLB miss rate gives a measure how often a TLB miss occurred +per instruction. And finally L1 DTLB miss ratio tells you how many +of your memory references required caused a TLB miss on average. + diff --git a/collectors/likwid/groups/nvidia_gpu_cc_ge_7/DATA.txt b/collectors/likwid/groups/nvidia_gpu_cc_ge_7/DATA.txt new file mode 100644 index 0000000..4171640 --- /dev/null +++ b/collectors/likwid/groups/nvidia_gpu_cc_ge_7/DATA.txt @@ -0,0 +1,16 @@ +SHORT Load to store ratio + +EVENTSET +GPU0 SMSP_SASS_INST_EXECUTED_OP_GLOBAL_LD_SUM +GPU1 SMSP_SASS_INST_EXECUTED_OP_GLOBAL_ST_SUM + +METRICS +Runtime (RDTSC) [s] time +Load to store ratio GPU0/GPU1 + +LONG +Formulas: +Load to store ratio = SMSP_SASS_INST_EXECUTED_OP_GLOBAL_LD_SUM/SMSP_SASS_INST_EXECUTED_OP_GLOBAL_ST_SUM +- +This is a metric to determine your load to store ratio. + diff --git a/collectors/likwid/groups/nvidia_gpu_cc_ge_7/FLOPS_DP.txt b/collectors/likwid/groups/nvidia_gpu_cc_ge_7/FLOPS_DP.txt new file mode 100644 index 0000000..7c6ae6c --- /dev/null +++ b/collectors/likwid/groups/nvidia_gpu_cc_ge_7/FLOPS_DP.txt @@ -0,0 +1,19 @@ +SHORT Double-precision floating point + +EVENTSET +GPU0 SMSP_SASS_THREAD_INST_EXECUTED_OP_DADD_PRED_ON_SUM +GPU1 SMSP_SASS_THREAD_INST_EXECUTED_OP_DMUL_PRED_ON_SUM +GPU2 SMSP_SASS_THREAD_INST_EXECUTED_OP_DFMA_PRED_ON_SUM + + +METRICS +Runtime (RDTSC) [s] time +DP [MFLOP/s] 1E-6*(GPU0+GPU1+(GPU2*2))/time + + +LONG +Formulas: +DP [MFLOP/s] = 1E-6*(SMSP_SASS_THREAD_INST_EXECUTED_OP_DADD_PRED_ON_SUM+SMSP_SASS_THREAD_INST_EXECUTED_OP_DMUL_PRED_ON_SUM+2*SMSP_SASS_THREAD_INST_EXECUTED_OP_DFMA_PRED_ON_SUM)/time +-- +This group measures the double-precision floating-point operations per second using the events +SMSP_SASS_THREAD_INST_EXECUTED_OP_D{ADD, MUL, FMA}_PRED_ON_SUM. diff --git a/collectors/likwid/groups/nvidia_gpu_cc_ge_7/FLOPS_HP.txt b/collectors/likwid/groups/nvidia_gpu_cc_ge_7/FLOPS_HP.txt new file mode 100644 index 0000000..76c78cd --- /dev/null +++ b/collectors/likwid/groups/nvidia_gpu_cc_ge_7/FLOPS_HP.txt @@ -0,0 +1,19 @@ +SHORT Half-precision floating point + +EVENTSET +GPU0 SMSP_SASS_THREAD_INST_EXECUTED_OP_HADD_PRED_ON_SUM +GPU1 SMSP_SASS_THREAD_INST_EXECUTED_OP_HMUL_PRED_ON_SUM +GPU2 SMSP_SASS_THREAD_INST_EXECUTED_OP_HFMA_PRED_ON_SUM + + +METRICS +Runtime (RDTSC) [s] time +HP [MFLOP/s] 1E-6*(GPU0+GPU1+(GPU2*2))/time + + +LONG +Formulas: +HP [MFLOP/s] = 1E-6*(SMSP_SASS_THREAD_INST_EXECUTED_OP_HADD_PRED_ON_SUM+SMSP_SASS_THREAD_INST_EXECUTED_OP_HMUL_PRED_ON_SUM+2*SMSP_SASS_THREAD_INST_EXECUTED_OP_HFMA_PRED_ON_SUM)/time +-- +This group measures the half-precision floating-point operations per second using the events +SMSP_SASS_THREAD_INST_EXECUTED_OP_H{ADD, MUL, FMA}_PRED_ON_SUM. diff --git a/collectors/likwid/groups/nvidia_gpu_cc_ge_7/FLOPS_SP.txt b/collectors/likwid/groups/nvidia_gpu_cc_ge_7/FLOPS_SP.txt new file mode 100644 index 0000000..cdc7a4e --- /dev/null +++ b/collectors/likwid/groups/nvidia_gpu_cc_ge_7/FLOPS_SP.txt @@ -0,0 +1,19 @@ +SHORT Single-precision floating point + +EVENTSET +GPU0 SMSP_SASS_THREAD_INST_EXECUTED_OP_FADD_PRED_ON_SUM +GPU1 SMSP_SASS_THREAD_INST_EXECUTED_OP_FMUL_PRED_ON_SUM +GPU2 SMSP_SASS_THREAD_INST_EXECUTED_OP_FFMA_PRED_ON_SUM + + +METRICS +Runtime (RDTSC) [s] time +SP [MFLOP/s] 1E-6*(GPU0+GPU1+(GPU2*2))/time + + +LONG +Formulas: +SP [MFLOP/s] = 1E-6*(SMSP_SASS_THREAD_INST_EXECUTED_OP_FADD_PRED_ON_SUM+SMSP_SASS_THREAD_INST_EXECUTED_OP_FMUL_PRED_ON_SUM+2*SMSP_SASS_THREAD_INST_EXECUTED_OP_FFMA_PRED_ON_SUM)/time +-- +This group measures the single-precision floating-point operations per second using the events +SMSP_SASS_THREAD_INST_EXECUTED_OP_F{ADD, MUL, FMA}_PRED_ON_SUM. diff --git a/collectors/likwid/groups/nvidia_gpu_cc_lt_7/DATA.txt b/collectors/likwid/groups/nvidia_gpu_cc_lt_7/DATA.txt new file mode 100644 index 0000000..b96bf08 --- /dev/null +++ b/collectors/likwid/groups/nvidia_gpu_cc_lt_7/DATA.txt @@ -0,0 +1,20 @@ +SHORT Load to store ratio + +EVENTSET +GPU0 GLOBAL_LOAD +GPU1 GLOBAL_STORE +GPU2 INST_EXECUTED +GPU3 ACTIVE_CYCLES + +METRICS +Runtime (RDTSC) [s] time +CPI GPU3/GPU2 +Load to store ratio GPU0/GPU1 + +LONG +Formulas: +CPI = ACTIVE_CYCLES/INST_EXECUTED +Load to store ratio = GENERIC_LOAD/GENERIC_STORE +- +This is a metric to determine your load to store ratio. + diff --git a/collectors/likwid/groups/nvidia_gpu_cc_lt_7/FLOPS_DP.txt b/collectors/likwid/groups/nvidia_gpu_cc_lt_7/FLOPS_DP.txt new file mode 100644 index 0000000..c03ac90 --- /dev/null +++ b/collectors/likwid/groups/nvidia_gpu_cc_lt_7/FLOPS_DP.txt @@ -0,0 +1,19 @@ +SHORT Double-precision floating point + +EVENTSET +GPU0 INST_EXECUTED_FP64_PIPE_S0 +GPU1 INST_EXECUTED_FP64_PIPE_S1 +GPU2 INST_EXECUTED_FP64_PIPE_S2 +GPU3 INST_EXECUTED_FP64_PIPE_S3 + + +METRICS +DP [MFLOP/s] 1E-6*(GPU0+GPU1+GPU2+GPU3)/time + + +LONG +Formulas: +DP [MFLOP/s] = 1E-6*(SUM(INST_EXECUTED_FP64_PIPE_S*))/time +-- +This group measures the double precision floating-point operations per second using the events +INST_EXECUTED_FP64_PIPE_S*. diff --git a/collectors/likwid/groups/nvidia_gpu_cc_lt_7/FLOPS_SP.txt b/collectors/likwid/groups/nvidia_gpu_cc_lt_7/FLOPS_SP.txt new file mode 100644 index 0000000..09f58ee --- /dev/null +++ b/collectors/likwid/groups/nvidia_gpu_cc_lt_7/FLOPS_SP.txt @@ -0,0 +1,20 @@ +SHORT Single-precision floating point + +EVENTSET +GPU0 INST_EXECUTED_FP64_PIPE_S0 +GPU1 INST_EXECUTED_FP64_PIPE_S1 +GPU2 INST_EXECUTED_FP64_PIPE_S2 +GPU3 INST_EXECUTED_FP64_PIPE_S3 + + +METRICS +SP [MFLOP/s] 1E-6*(GPU0+GPU1+GPU2+GPU3)/time + + +LONG +Formulas: +SP [MFLOP/s] = 1E-6*(SUM(INST_EXECUTED_FP64_PIPE_S*))/time +-- +This group measures the single precision floating-point operations per second using the events +INST_EXECUTED_FP64_PIPE_S*. Unfortunately, not all GPUs provide these events although they provide +a metric for SP FP operations which are currently not usable with LIKWID. diff --git a/collectors/likwid/groups/pentiumm/BRANCH.txt b/collectors/likwid/groups/pentiumm/BRANCH.txt new file mode 100644 index 0000000..269a500 --- /dev/null +++ b/collectors/likwid/groups/pentiumm/BRANCH.txt @@ -0,0 +1,17 @@ +SHORT Branch prediction miss rate/ratio + +EVENTSET +PMC0 BR_INST_EXEC +PMC1 BR_MISSP_EXEC + +METRICS +Runtime (RDTSC) [s] time +Branch misprediction ratio PMC1/PMC0 + +LONG +Formulas: +Branch misprediction ratio = BR_MISSP_EXEC / BR_INST_EXEC +- +The rates state how often on average a branch or a mispredicted branch occurred +per instruction retired in total. The branch misprediction ratio sets directly +into relation what ratio of all branch instruction where mispredicted. diff --git a/collectors/likwid/groups/pentiumm/CPI.txt b/collectors/likwid/groups/pentiumm/CPI.txt new file mode 100644 index 0000000..ae4aa26 --- /dev/null +++ b/collectors/likwid/groups/pentiumm/CPI.txt @@ -0,0 +1,22 @@ +SHORT Cycles per instruction + +EVENTSET +PMC0 UOPS_RETIRED +PMC1 CPU_CLK_UNHALTED + +METRICS +Runtime (RDTSC) [s] time +CPI PMC1/PMC0 +IPC PMC0/PMC1 + +LONG +Formulas: +CPI = CPU_CLK_UNHALTED/UOPS_RETIRED +IPC = UOPS_RETIRED/CPU_CLK_UNHALTED +- +This group measures how efficient the processor works with +regard to instruction throughput. Also important as a standalone +metric is UOPS_RETIRED as it tells you how many uops +you need to execute for a task. An optimization might show very +low CPI values but execute many more instruction for it. + diff --git a/collectors/likwid/groups/pentiumm/FLOPS_DP.txt b/collectors/likwid/groups/pentiumm/FLOPS_DP.txt new file mode 100644 index 0000000..058a64e --- /dev/null +++ b/collectors/likwid/groups/pentiumm/FLOPS_DP.txt @@ -0,0 +1,20 @@ +SHORT Double Precision MFLOP/s + +EVENTSET +PMC0 EMON_SSE_SSE2_COMP_INST_RETIRED_PACKED_DP +PMC1 EMON_SSE_SSE2_COMP_INST_RETIRED_SCALAR_DP + +METRICS +Runtime (RDTSC) [s] time +DP [MFLOP/s] 1.0E-06*(PMC0*2.0+PMC1)/time +Packed [MUOPS/s] 1.0E-06*(PMC0)/time +Scalar [MUOPS/s] 1.0E-06*PMC1/time + +LONG +Formulas: +DP [MFLOP/s] = (EMON_SSE_SSE2_COMP_INST_RETIRED_PACKED_DP*2 + EMON_SSE_SSE2_COMP_INST_RETIRED_SCALAR_DP )/ runtime +Packed [MUOPS/s] = 1.0E-06*(EMON_SSE_SSE2_COMP_INST_RETIRED_PACKED_DP)/time +Scalar [MUOPS/s] = 1.0E-06*EMON_SSE_SSE2_COMP_INST_RETIRED_SCALAR_DP/time +- +SSE scalar and packed double precision FLOP rates. + diff --git a/collectors/likwid/groups/pentiumm/FLOPS_SP.txt b/collectors/likwid/groups/pentiumm/FLOPS_SP.txt new file mode 100644 index 0000000..d70b835 --- /dev/null +++ b/collectors/likwid/groups/pentiumm/FLOPS_SP.txt @@ -0,0 +1,18 @@ +SHORT Single Precision MFLOP/s + +EVENTSET +PMC0 EMON_SSE_SSE2_COMP_INST_RETIRED_ALL_SP +PMC1 EMON_SSE_SSE2_COMP_INST_RETIRED_SCALAR_SP + +METRICS +Runtime (RDTSC) [s] time +SP [MFLOP/s] 1.0E-06*(PMC0)/time +Scalar [MUOPS/s] 1.0E-06*(PMC1)/time + +LONG +Formulas: +SP [MFLOP/s] = (EMON_SSE_SSE2_COMP_INST_RETIRED_ALL_SP)/ runtime +Scalar [MUOPS/s] = (EMON_SSE_SSE2_COMP_INST_RETIRED_SCALAR_SP)/ runtime +- +SSE scalar and packed single precision FLOP rates. + diff --git a/collectors/likwid/groups/pentiumm/L3.txt b/collectors/likwid/groups/pentiumm/L3.txt new file mode 100644 index 0000000..2ed5293 --- /dev/null +++ b/collectors/likwid/groups/pentiumm/L3.txt @@ -0,0 +1,30 @@ +SHORT L3 cache bandwidth in MBytes/s + +EVENTSET +PMC0 L2_LINES_IN_ALL_ALL +PMC1 L2_LINES_OUT_ALL_ALL + +METRICS +Runtime (RDTSC) [s] time +L3 load bandwidth [MBytes/s] 1.0E-06*PMC0*64.0/time +L3 load data volume [GBytes] 1.0E-09*PMC0*64.0 +L3 evict bandwidth [MBytes/s] 1.0E-06*PMC1*64.0/time +L3 evict data volume [GBytes] 1.0E-09*PMC1*64.0 +L3 bandwidth [MBytes/s] 1.0E-06*(PMC0+PMC1)*64.0/time +L3 data volume [GBytes] 1.0E-09*(PMC0+PMC1)*64.0 + +LONG +Formulas: +L3 load bandwidth [MBytes/s] = 1.0E-06*L2_LINES_IN_ALL_ALL*64.0/time +L3 load data volume [GBytes] = 1.0E-09*L2_LINES_IN_ALL_ALL*64.0 +L3 evict bandwidth [MBytes/s] = 1.0E-06*L2_LINES_OUT_ALL_ALL*64.0/time +L3 evict data volume [GBytes] = 1.0E-09*L2_LINES_OUT_ALL_ALL*64.0 +L3 bandwidth [MBytes/s] = 1.0E-06*(L2_LINES_IN_ALL_ALL+L2_LINES_OUT_ALL_ALL)*64/time +L3 data volume [GBytes] = 1.0E-09*(L2_LINES_IN_ALL_ALL+L2_LINES_OUT_ALL_ALL)*64 +- +Profiling group to measure L3 cache bandwidth. The bandwidth is computed by the +number of cache line allocated in the L2 and the number of modified cache lines +evicted from the L2. The group also output total data volume transferred between +L2. Note that this bandwidth also includes data transfers due to a write +allocate load on a store miss in L2. + diff --git a/collectors/likwid/groups/phi/CACHE.txt b/collectors/likwid/groups/phi/CACHE.txt new file mode 100644 index 0000000..01ac5e4 --- /dev/null +++ b/collectors/likwid/groups/phi/CACHE.txt @@ -0,0 +1,22 @@ +SHORT L1 compute to data access ratio + +EVENTSET +PMC0 VPU_ELEMENTS_ACTIVE +PMC1 DATA_READ_OR_WRITE + +METRICS +Runtime (RDTSC) [s] time +L1 compute intensity PMC0/PMC1 + +LONG +Formulas: +L1 compute intensity = VPU_ELEMENTS_ACTIVE/DATA_READ_OR_WRITE +- +These metric is a way to measure the computational density of an +application, or how many computations it is performing on average for each +piece of data loaded. L1 compute to data access ratio should be +used to judge suitability of an application for running on the Intel MIC +architecture. Applications that will perform well on the Intel MIC +architecture should be vectorized, and ideally be able to perform multiple +operations on the same pieces of data (or same cache lines). + diff --git a/collectors/likwid/groups/phi/COMPUTE_TO_DATA_RATIO.txt b/collectors/likwid/groups/phi/COMPUTE_TO_DATA_RATIO.txt new file mode 100644 index 0000000..6fdd008 --- /dev/null +++ b/collectors/likwid/groups/phi/COMPUTE_TO_DATA_RATIO.txt @@ -0,0 +1,22 @@ +SHORT L2 compute to data access ratio + +EVENTSET +PMC0 VPU_ELEMENTS_ACTIVE +PMC1 DATA_READ_MISS_OR_WRITE_MISS + +METRICS +Runtime (RDTSC) [s] time +L2 compute intensity PMC0/PMC1 + +LONG +Formulas: +L2 compute intensity = VPU_ELEMENTS_ACTIVE/DATA_READ_MISS_OR_WRITE_MISS +- +These metric is a way to measure the computational density of an +application, or how many computations it is performing on average for each +piece of data loaded. L2 compute to data access ratio should be +used to judge suitability of an application for running on the Intel MIC +architecture. Applications that will perform well on the Intel MIC +architecture should be vectorized, and ideally be able to perform multiple +operations on the same pieces of data (or same cache lines). + diff --git a/collectors/likwid/groups/phi/CPI.txt b/collectors/likwid/groups/phi/CPI.txt new file mode 100644 index 0000000..f3d8b4e --- /dev/null +++ b/collectors/likwid/groups/phi/CPI.txt @@ -0,0 +1,23 @@ +SHORT Cycles per instruction + +EVENTSET +PMC0 INSTRUCTIONS_EXECUTED +PMC1 CPU_CLK_UNHALTED + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] PMC1*inverseClock +CPI PMC1/PMC0 +IPC PMC0/PMC1 + +LONG +Formulas: +CPI = CPU_CLK_UNHALTED/INSTRUCTIONS_EXECUTED +IPC = INSTRUCTIONS_EXECUTED/CPU_CLK_UNHALTED +- +This group measures how efficient the processor works with +regard to instruction throughput. Also important as a standalone +metric is INSTRUCTIONS_RETIRED as it tells you how many instruction +you need to execute for a task. An optimization might show very +low CPI values but execute many more instruction for it. + diff --git a/collectors/likwid/groups/phi/MEM.txt b/collectors/likwid/groups/phi/MEM.txt new file mode 100644 index 0000000..8899592 --- /dev/null +++ b/collectors/likwid/groups/phi/MEM.txt @@ -0,0 +1,18 @@ +SHORT Memory bandwidth + +EVENTSET +PMC0 DATA_READ_MISS_OR_WRITE_MISS +PMC1 DATA_CACHE_LINES_WRITTEN_BACK + + +METRICS +Runtime (RDTSC) [s] time +Memory bandwidth [MBytes/s] 1.0E-06*(PMC0+PMC1)*64.0/time +Memory data volume [GBytes] 1.0E-09*(PMC0+PMC1)*64.0 + +LONG +Formulas: +Memory bandwidth [MBytes/s] = 1.0E-06*(DATA_READ_MISS_OR_WRITE_MISS+DATA_CACHE_LINES_WRITTEN_BACK)*64.0/time +Memory data volume [GBytes] = 1.0E-09*(DATA_READ_MISS_OR_WRITE_MISS+DATA_CACHE_LINES_WRITTEN_BACK)*64.0 +- +Total memory bandwidth and data volume. diff --git a/collectors/likwid/groups/phi/MEM1.txt b/collectors/likwid/groups/phi/MEM1.txt new file mode 100644 index 0000000..c9f7fb6 --- /dev/null +++ b/collectors/likwid/groups/phi/MEM1.txt @@ -0,0 +1,18 @@ +SHORT L2 write misses + +EVENTSET +PMC0 L2_DATA_WRITE_MISS_MEM_FILL + +METRICS +Runtime (RDTSC) [s] time +L2 RFO bandwidth [MBytes/s] 1.0E-06*PMC0*64.0/time +L2 RFO data volume [GBytes] 1.0E-09*PMC0*64.0 + +LONG +Formulas: +L2 RFO bandwidth [MBytes/s] = 1.0E-06*L2_DATA_WRITE_MISS_MEM_FILL*64.0/time +L2 RFO data volume [GBytes] = 1.0E-09*L2_DATA_WRITE_MISS_MEM_FILL*64.0 +- +Bandwidth and data volume fetched from memory due to a L2 data write miss. These +fetches are commonly called write-allocate loads or read-for-ownership (RFO). + diff --git a/collectors/likwid/groups/phi/MEM2.txt b/collectors/likwid/groups/phi/MEM2.txt new file mode 100644 index 0000000..d44a823 --- /dev/null +++ b/collectors/likwid/groups/phi/MEM2.txt @@ -0,0 +1,17 @@ +SHORT L2 read misses + +EVENTSET +PMC0 L2_DATA_READ_MISS_MEM_FILL + +METRICS +Runtime (RDTSC) [s] time +L2 read bandwidth [MBytes/s] 1.0E-06*PMC0*64.0/time +L2 read data volume [GBytes] 1.0E-09*PMC0*64.0 + +LONG +Formulas: +L2 read bandwidth [MBytes/s] = 1.0E-06*L2_DATA_READ_MISS_MEM_FILL*64.0/time +L2 read data volume [GBytes] = 1.0E-09*L2_DATA_READ_MISS_MEM_FILL*64.0 +- +The data volume and bandwidth caused by read misses in the L2 cache. + diff --git a/collectors/likwid/groups/phi/MEM3.txt b/collectors/likwid/groups/phi/MEM3.txt new file mode 100644 index 0000000..73de570 --- /dev/null +++ b/collectors/likwid/groups/phi/MEM3.txt @@ -0,0 +1,17 @@ +SHORT HW prefetch transfers + +EVENTSET +PMC0 HWP_L2MISS + +METRICS +Runtime (RDTSC) [s] time +Prefetch bandwidth [MBytes/s] 1.0E-06*PMC0*64.0/time +Prefetch data volume [GBytes] 1.0E-09*PMC0*64.0 + +LONG +Formulas: +Prefetch bandwidth [MBytes/s] = 1.0E-06*HWP_L2MISS*64.0/time +Prefetch data volume [GBytes] = 1.0E-09*HWP_L2MISS*64.0 +- +The bandwidth and data volume caused by L2 misses from the hardware prefetcher. + diff --git a/collectors/likwid/groups/phi/MEM4.txt b/collectors/likwid/groups/phi/MEM4.txt new file mode 100644 index 0000000..9e892bd --- /dev/null +++ b/collectors/likwid/groups/phi/MEM4.txt @@ -0,0 +1,17 @@ +SHORT L2 victom requests + +EVENTSET +PMC0 L2_VICTIM_REQ_WITH_DATA + +METRICS +Runtime (RDTSC) [s] time +Victim bandwidth [MBytes/s] 1.0E-06*PMC0*64.0/time +Victim data volume [GBytes] 1.0E-09*PMC0*64.0 + +LONG +Formulas: +Victim bandwidth [MBytes/s] = 1.0E-06*L2_VICTIM_REQ_WITH_DATA*64.0/time +Victim data volume [GBytes] = 1.0E-09*L2_VICTIM_REQ_WITH_DATA*64.0 +- +Data volume and bandwidth caused by cache line victims. + diff --git a/collectors/likwid/groups/phi/MEM5.txt b/collectors/likwid/groups/phi/MEM5.txt new file mode 100644 index 0000000..49acb98 --- /dev/null +++ b/collectors/likwid/groups/phi/MEM5.txt @@ -0,0 +1,19 @@ +SHORT L2 snoop hits + +EVENTSET +PMC0 SNP_HITM_L2 + +METRICS +Runtime (RDTSC) [s] time +Snoop bandwidth [MBytes/s] 1.0E-06*PMC0*64.0/time +Snoop data volume [GBytes] 1.0E-09*PMC0*64.0 + +LONG +Formulas: +Snoop bandwidth [MBytes/s] = 1.0E-06*SNP_HITM_L2*64.0/time +Snoop data volume [GBytes] = 1.0E-09*SNP_HITM_L2*64.0 +- +Snoop traffic caused by HITM requests. HITM requests are L2 requests that +are served by another core's L2 cache but the remote cache line is in modified +state. + diff --git a/collectors/likwid/groups/phi/MEM6.txt b/collectors/likwid/groups/phi/MEM6.txt new file mode 100644 index 0000000..835faf8 --- /dev/null +++ b/collectors/likwid/groups/phi/MEM6.txt @@ -0,0 +1,17 @@ +SHORT L2 read misses + +EVENTSET +PMC0 L2_READ_MISS + +METRICS +Runtime (RDTSC) [s] time +L2 read bandwidth [MBytes/s] 1.0E-06*PMC0*64.0/time +L2 read data volume [GBytes] 1.0E-09*PMC0*64.0 + +LONG +Formulas: +L2 read bandwidth [MBytes/s] = 1.0E-06*L2_READ_MISS*64.0/time +L2 read data volume [GBytes] = 1.0E-09*L2_READ_MISS*64.0 +- +Data volume and bandwidth caused by read misses in the L2 cache. + diff --git a/collectors/likwid/groups/phi/MEM_READ.txt b/collectors/likwid/groups/phi/MEM_READ.txt new file mode 100644 index 0000000..fb107b0 --- /dev/null +++ b/collectors/likwid/groups/phi/MEM_READ.txt @@ -0,0 +1,20 @@ +SHORT Memory read bandwidth + +EVENTSET +PMC0 DATA_READ_MISS +PMC1 HWP_L2MISS + + +METRICS +Runtime (RDTSC) [s] time +Memory read bandwidth [MBytes/s] 1.0E-06*(PMC0+PMC1)*64.0/time +Memory read data volume [GBytes] 1.0E-09*(PMC0+PMC1)*64.0 + +LONG +Formulas: +Memory read bandwidth [MBytes/s] = 1.0E-06*(L2_DATA_READ_MISS_MEM_FILL+HWP_L2MISS)*64.0/time +Memory read data volume [GBytes] = 1.0E-09*(L2_DATA_READ_MISS_MEM_FILL+HWP_L2MISS)*64.0 +- +Bandwidth and data volume of read operations from the memory to L2 cache. The +metric is introduced in the book 'Intel Xeon Phi Coprocessor High-Performance +Programming' by James Jeffers and James Reinders. diff --git a/collectors/likwid/groups/phi/MEM_WRITE.txt b/collectors/likwid/groups/phi/MEM_WRITE.txt new file mode 100644 index 0000000..01043fd --- /dev/null +++ b/collectors/likwid/groups/phi/MEM_WRITE.txt @@ -0,0 +1,20 @@ +SHORT Memory write bandwidth + +EVENTSET +PMC0 L2_VICTIM_REQ_WITH_DATA +PMC1 SNP_HITM_L2 + + +METRICS +Runtime (RDTSC) [s] time +Memory write bandwidth [MBytes/s] 1.0E-06*(PMC0+PMC1)*64.0/time +Memory write data volume [GBytes] 1.0E-09*(PMC0+PMC1)*64.0 + +LONG +Formulas: +Memory write bandwidth [MBytes/s] = 1.0E-06*(L2_VICTIM_REQ_WITH_DATA+SNP_HITM_L2)*64.0/time +Memory write data volume [GBytes] = 1.0E-09*(L2_VICTIM_REQ_WITH_DATA+SNP_HITM_L2)*64.0 +- +Bandwidth and data volume of write operations from the L2 cache to memory. The +metric is introduced in the book 'Intel Xeon Phi Coprocessor High-Performance +Programming' by James Jeffers and James Reinders. diff --git a/collectors/likwid/groups/phi/PAIRING.txt b/collectors/likwid/groups/phi/PAIRING.txt new file mode 100644 index 0000000..ce3627c --- /dev/null +++ b/collectors/likwid/groups/phi/PAIRING.txt @@ -0,0 +1,21 @@ +SHORT Pairing ratio + +EVENTSET +PMC0 INSTRUCTIONS_EXECUTED +PMC1 INSTRUCTIONS_EXECUTED_V_PIPE + +METRICS +Runtime (RDTSC) [s] time +V-pipe ratio PMC1/PMC0 +Pairing ratio PMC1/(PMC0-PMC1) + +LONG +Formulas: +V-pipe ratio = INSTRUCTIONS_EXECUTED_V_PIPE/INSTRUCTIONS_EXECUTED +Pairing ratio = INSTRUCTIONS_EXECUTED_V_PIPE/(INSTRUCTIONS_EXECUTED-INSTRUCTIONS_EXECUTED_V_PIPE) +- +Each hardware thread on the Xeon Phi can execute two instruction simultaneously, +one in the U-pipe and one in the V-pipe. But this is only possible if the +instructions can be paired. The instructions executed in paired fashion are counted +by the event INSTRUCTIONS_EXECUTED_V_PIPE. The event INSTRUCTIONS_EXECUTED increments +for each instruction, hence the maximal increase per cycle can be 2. diff --git a/collectors/likwid/groups/phi/READ_MISS_RATIO.txt b/collectors/likwid/groups/phi/READ_MISS_RATIO.txt new file mode 100644 index 0000000..dbdaad5 --- /dev/null +++ b/collectors/likwid/groups/phi/READ_MISS_RATIO.txt @@ -0,0 +1,15 @@ +SHORT Miss ratio fof data reads + +EVENTSET +PMC0 DATA_READ +PMC1 DATA_READ_MISS + +METRICS +Runtime (RDTSC) [s] time +Read miss ratio PMC1/PMC0 + +LONG +Formulas: +Read miss ratio = DATA_READ_MISS/DATA_READ +-- +Miss ratio for data reads. diff --git a/collectors/likwid/groups/phi/TLB.txt b/collectors/likwid/groups/phi/TLB.txt new file mode 100644 index 0000000..6f00359 --- /dev/null +++ b/collectors/likwid/groups/phi/TLB.txt @@ -0,0 +1,23 @@ +SHORT TLB Misses + +EVENTSET +PMC0 LONG_DATA_PAGE_WALK +PMC1 DATA_PAGE_WALK + +METRICS +Runtime (RDTSC) [s] time +L1 TLB misses [misses/s] PMC1/time +L2 TLB misses [misses/s] PMC0/time +L1 TLB misses per L2 TLB miss PMC1/PMC0 + +LONG +Formulas: +L1 TLB misses [misses/s] = DATA_PAGE_WALK/time +L2 TLB misses [misses/s] = LONG_DATA_PAGE_WALK/time +L1 TLB misses per L2 TLB miss = DATA_PAGE_WALK/LONG_DATA_PAGE_WALK +- +Analysis of the layered TLB of the Intel Xeon Phi. According to the book +'Intel Xeon Phi Coprocessor High-Performance Programming' by James Jeffers and +James Reinders, a high L1 TLB misses per L2 TLB miss ratio suggests that your +working set fits into the L2 TLB but not in L1 TLB. Using large pages may be +beneficial. diff --git a/collectors/likwid/groups/phi/TLB_L1.txt b/collectors/likwid/groups/phi/TLB_L1.txt new file mode 100644 index 0000000..d826d04 --- /dev/null +++ b/collectors/likwid/groups/phi/TLB_L1.txt @@ -0,0 +1,23 @@ +SHORT L1 TLB misses + +EVENTSET +PMC0 DATA_PAGE_WALK +PMC1 DATA_READ_OR_WRITE + +METRICS +Runtime (RDTSC) [s] time +L1 TLB misses [misses/s] PMC0/time +L1 TLB miss ratio PMC0/PMC1 + +LONG +Formulas: +L1 TLB misses [misses/s] = DATA_PAGE_WALK/time +L1 TLB miss ratio = DATA_PAGE_WALK/DATA_READ_OR_WRITE +- +This performance group measures the L1 TLB misses. A L1 TLB miss that hits the +L2 TLB has a penelty of about 25 cycles for 4kB pages. For 2MB pages, the penelty +for a L1 TLB miss that hits L2 TLB is about 8 cycles. The minimal L1 TLB miss ratio +is about 1/64, so a high ratio indicates a bad spartial locality. Data of a page +is only partly accessed. It can also indicate trashing because when multiple pages +are accessed in a loop iteration, the size and associativity is not sufficient to +hold all pages. diff --git a/collectors/likwid/groups/phi/TLB_L2.txt b/collectors/likwid/groups/phi/TLB_L2.txt new file mode 100644 index 0000000..9a95125 --- /dev/null +++ b/collectors/likwid/groups/phi/TLB_L2.txt @@ -0,0 +1,21 @@ +SHORT L2 TLB misses + +EVENTSET +PMC0 LONG_DATA_PAGE_WALK +PMC1 DATA_READ_OR_WRITE + +METRICS +Runtime (RDTSC) [s] time +L2 TLB misses [misses/s] PMC0/time +L2 TLB miss ratio PMC0/PMC1 + +LONG +Formulas: +L2 TLB misses [misses/s] = LONG_DATA_PAGE_WALK/time +L2 TLB miss ratio = LONG_DATA_PAGE_WALK/DATA_READ_OR_WRITE +- +This performance group measures the L2 TLB misses. A L2 TLB miss has a penelty +of at least 100 cycles, hence it is important to avoid them. A high ratio can +indicate trashing because when multiple pages are accessed in a loop iteration, +the size and associativity is not sufficient to hold all pages. This would also +result in a bad ratio for the L1 TLB. diff --git a/collectors/likwid/groups/phi/VECTOR.txt b/collectors/likwid/groups/phi/VECTOR.txt new file mode 100644 index 0000000..b6ec6a6 --- /dev/null +++ b/collectors/likwid/groups/phi/VECTOR.txt @@ -0,0 +1,21 @@ +SHORT Vectorization intensity + +EVENTSET +PMC0 VPU_INSTRUCTIONS_EXECUTED +PMC1 VPU_ELEMENTS_ACTIVE + +METRICS +Runtime (RDTSC) [s] time +Vectorization intensity PMC1/PMC0 + +LONG +Formulas: +Vectorization intensity = VPU_ELEMENTS_ACTIVE / VPU_INSTRUCTIONS_EXECUTED +- +Vector instructions include instructions that perform floating-point +operations, instructions that load vector registers from memory and store them +to memory, instructions to manipulate vector mask registers, and other special +purpose instructions such as vector shuffle. +According to the book 'Intel Xeon Phi Coprocessor High-Performance Programming' +by James Jeffers and James Reinders, the vectorization intensity should be >=8 +for double precision and >=16 for single precision. diff --git a/collectors/likwid/groups/phi/VECTOR2.txt b/collectors/likwid/groups/phi/VECTOR2.txt new file mode 100644 index 0000000..52b3c59 --- /dev/null +++ b/collectors/likwid/groups/phi/VECTOR2.txt @@ -0,0 +1,20 @@ +SHORT Vector unit usage + +EVENTSET +PMC0 VPU_INSTRUCTIONS_EXECUTED +PMC1 VPU_STALL_REG + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] PMC1*inverseClock +VPU stall ratio [%] 100*(VPU_STALL_REG/PMC0) + +LONG +Formulas: +VPU stall ratio [%] = 100*(VPU_STALL_REG/VPU_INSTRUCTIONS_EXECUTED) +-- +This group measures how efficient the processor works with +regard to vectorization instruction throughput. The event VPU_STALL_REG counts +the VPU stalls due to data dependencies. Dependencies are read-after-write, +write-after-write and write-after-read. + diff --git a/collectors/likwid/groups/phi/VPU_FILL_RATIO_DBL.txt b/collectors/likwid/groups/phi/VPU_FILL_RATIO_DBL.txt new file mode 100644 index 0000000..6e8065c --- /dev/null +++ b/collectors/likwid/groups/phi/VPU_FILL_RATIO_DBL.txt @@ -0,0 +1,18 @@ +SHORT VPU filling for double precisiof data + +EVENTSET +PMC0 VPU_INSTRUCTIONS_EXECUTED +PMC1 VPU_ELEMENTS_ACTIVE + +METRICS +Runtime (RDTSC) [s] time +VPU fill ratio PMC0*8/PMC1 + +LONG +Formulas: +VPU fill ratio = VPU_INSTRUCTIONS_EXECUTED*8/VPU_ELEMENTS_ACTIVE +-- +This performance group measures the number of vector instructions that are +performed on each vector loaded to the VPU. It is important to increate the +ratio to get a high throughput because memory accesses (loading data to the VPU) +are expensive. diff --git a/collectors/likwid/groups/phi/VPU_PAIRING.txt b/collectors/likwid/groups/phi/VPU_PAIRING.txt new file mode 100644 index 0000000..024919b --- /dev/null +++ b/collectors/likwid/groups/phi/VPU_PAIRING.txt @@ -0,0 +1,20 @@ +SHORT VPU pairing ratio + +EVENTSET +PMC0 VPU_INSTRUCTIONS_EXECUTED +PMC1 VPU_INSTRUCTIONS_EXECUTED_V_PIPE + +METRICS +Runtime (RDTSC) [s] time +V-pipe ratio PMC1/PMC0 +Pairing ratio PMC1/(PMC0-PMC1) + +LONG +Formulas: +V-pipe ratio = VPU_INSTRUCTIONS_EXECUTED_V_PIPE/VPU_INSTRUCTIONS_EXECUTED +Pairing ratio = VPU_INSTRUCTIONS_EXECUTED_V_PIPE/(VPU_INSTRUCTIONS_EXECUTED-VPU_INSTRUCTIONS_EXECUTED_V_PIPE) +-- +This performance group measures the pairing ratio of vector instructions. The +V-pipe can only execute a subset of all instruction, the main workload is done +by the U-pipe. A higher throughput can be achieved if the pairing ratio is +increased. diff --git a/collectors/likwid/groups/phi/VPU_READ_MISS_RATIO.txt b/collectors/likwid/groups/phi/VPU_READ_MISS_RATIO.txt new file mode 100644 index 0000000..cf04c5f --- /dev/null +++ b/collectors/likwid/groups/phi/VPU_READ_MISS_RATIO.txt @@ -0,0 +1,16 @@ +SHORT Miss ratio for VPU data reads + +EVENTSET +PMC0 VPU_DATA_READ +PMC1 VPU_DATA_READ_MISS + +METRICS +Runtime (RDTSC) [s] time +VPU read miss ratio PMC1/PMC0 + +LONG +Formulas: +VPU read miss ratio = PMC1/PMC0 +-- +This performance group determines the ratio between reads and reads that miss +the cache and are issued by the VPU. diff --git a/collectors/likwid/groups/phi/VPU_WRITE_MISS_RATIO.txt b/collectors/likwid/groups/phi/VPU_WRITE_MISS_RATIO.txt new file mode 100644 index 0000000..cebf3c7 --- /dev/null +++ b/collectors/likwid/groups/phi/VPU_WRITE_MISS_RATIO.txt @@ -0,0 +1,16 @@ +SHORT Miss ratio for VPU data writes + +EVENTSET +PMC0 VPU_DATA_WRITE +PMC1 VPU_DATA_WRITE_MISS + +METRICS +Runtime (RDTSC) [s] time +VPU write miss ratio PMC1/PMC0 + +LONG +Formulas: +VPU write miss ratio = PMC1/PMC0 +-- +This performance group determines the ratio between writes and writes that miss +the cache and are issued by the VPU. diff --git a/collectors/likwid/groups/phi/WRITE_MISS_RATIO.txt b/collectors/likwid/groups/phi/WRITE_MISS_RATIO.txt new file mode 100644 index 0000000..1e92c76 --- /dev/null +++ b/collectors/likwid/groups/phi/WRITE_MISS_RATIO.txt @@ -0,0 +1,15 @@ +SHORT Miss ratio fof data writes + +EVENTSET +PMC0 DATA_WRITE +PMC1 DATA_WRITE_MISS + +METRICS +Runtime (RDTSC) [s] time +Write miss ratio PMC1/PMC0 + +LONG +Formulas: +Write miss ratio = DATA_WRITE_MISS/DATA_WRITE +-- +Miss ratio fof data writes. diff --git a/collectors/likwid/groups/power8/BRANCH.txt b/collectors/likwid/groups/power8/BRANCH.txt new file mode 100644 index 0000000..870bb9d --- /dev/null +++ b/collectors/likwid/groups/power8/BRANCH.txt @@ -0,0 +1,30 @@ +SHORT Branch prediction miss rate/ratio + +EVENTSET +PMC0 PM_BR_PRED_BR_CMPL +PMC1 PM_BR_PRED_CCACHE_CMPL +PMC2 PM_BR_PRED_CR_CMPL +PMC3 PM_BR_MPRED_CMPL +PMC4 PM_RUN_INST_CMPL +PMC5 PM_RUN_CYC + +METRICS +Runtime (RDTSC) [s] time +CPI PMC5/PMC4 +Branch rate (PMC0+PMC1+PMC2)/PMC4 +Branch misprediction rate PMC3/PMC4 +Branch misprediction ratio PMC4/(PMC0+PMC1+PMC2) +Instructions per branch PMC4/(PMC0+PMC1+PMC2) + +LONG +Formulas: +Branch rate = BR_INST_RETIRED_ALL_BRANCHES/INSTR_RETIRED_ANY +Branch misprediction rate = BR_MISP_RETIRED_ALL_BRANCHES/INSTR_RETIRED_ANY +Branch misprediction ratio = BR_MISP_RETIRED_ALL_BRANCHES/BR_INST_RETIRED_ALL_BRANCHES +Instructions per branch = INSTR_RETIRED_ANY/BR_INST_RETIRED_ALL_BRANCHES +- +The rates state how often in average a branch or a mispredicted branch occured +per instruction retired in total. The Branch misprediction ratio sets directly +into relation what ratio of all branch instruction where mispredicted. +Instructions per branch is 1/Branch rate. + diff --git a/collectors/likwid/groups/power8/CPISTACK1.txt b/collectors/likwid/groups/power8/CPISTACK1.txt new file mode 100644 index 0000000..aa8a643 --- /dev/null +++ b/collectors/likwid/groups/power8/CPISTACK1.txt @@ -0,0 +1,35 @@ +SHORT First level of IBM CPI stack + +EVENTSET +PMC0 PM_CMPLU_STALL_THRD +PMC1 PM_GCT_EMPTY_CYC +PMC3 PM_CMPLU_STALL +PMC4 PM_RUN_INST_CMPL +PMC5 PM_RUN_CYC + +METRICS +CPI PMC5/PMC4 +Stall cycles PMC3 +Stall cycle ratio PMC3/PMC5 +Thread blocked cycles PMC0 +Thread blocked cycle ratio PMC0/PMC5 +GCT empty cycles PMC1 +GCT empty cycle ratio PMC1/PM5 + + + + +LONG +Formulas: +Stall cycles = PM_CMPLU_STALL +Stall cycle ratio = PM_CMPLU_STALL/PM_RUN_CYC +Thread blocked cycles = PM_CMPLU_STALL_THRD +Thread blocked cycle ratio = PM_CMPLU_STALL_THRD/PM_RUN_CYC +GCT empty cycles = PM_GCT_EMPTY_CYC +GCT empty cycle ratio = PM_GCT_EMPTY_CYC/PM_RUN_CYC +-- +First level of IBM CPI stack. IBM names Stalled Cycles, Waiting to Complete, +Thread Blocked, Completion Table Empty, Other and Completion Cycles. For some +there are no clearly identifiable events, so this group concentrates on +Stalled Cycles (PM_CMPLU_STALL), Thread Blocked (PM_CMPLU_STALL_THRD), +Completion Table Empty (PM_GCT_EMPTY_CYC) and Other (PM_CMPLU_STALL_OTHER_CMPL). diff --git a/collectors/likwid/groups/power8/DATA.txt b/collectors/likwid/groups/power8/DATA.txt new file mode 100644 index 0000000..bc3b893 --- /dev/null +++ b/collectors/likwid/groups/power8/DATA.txt @@ -0,0 +1,23 @@ +SHORT Load to store ratio + +EVENTSET +PMC0 PM_LD_CMPL +PMC1 PM_ST_CMPL +PMC4 PM_RUN_INST_CMPL +PMC5 PM_RUN_CYC + +METRICS +Runtime (RDTSC) [s] time +CPI PMC5/PMC4 +Load to store ratio PMC0/PMC1 +Load ratio PMC0/PMC4 +Store ratio PMC1/PMC4 + +LONG +Formulas: +Load to store ratio = PM_LD_CMPL/PM_ST_CMPL +Load ratio = PM_LD_CMPL/PM_RUN_INST_CMPL +Store ratio = PM_ST_CMPL/PM_RUN_INST_CMPL +- +This is a metric to determine your load to store ratio. + diff --git a/collectors/likwid/groups/power8/FLOPS_1_2.txt b/collectors/likwid/groups/power8/FLOPS_1_2.txt new file mode 100644 index 0000000..27138d5 --- /dev/null +++ b/collectors/likwid/groups/power8/FLOPS_1_2.txt @@ -0,0 +1,24 @@ +SHORT Group 121 as used in IBM Parallel Environment Developer Edition + +EVENTSET +PMC0 PM_VSU0_1FLOP +PMC1 PM_VSU1_1FLOP +PMC2 PM_VSU0_2FLOP +PMC3 PM_VSU1_2FLOP +PMC4 PM_RUN_INST_CMPL +PMC5 PM_RUN_CYC + +METRICS +CPI PMC5/PMC4 +One FLOP ops PMC0+PMC1 +Two FLOPs ops PMC2+PMC3 +[MFLOP/s] 1E-6*(PMC0+PMC1+((PMC2+PMC3)*2))/time + +LONG +Formulas: +CPI = PM_RUN_CYC/PM_RUN_INST_CMPL +One FLOP ops = PM_VSU0_1FLOP+PM_VSU1_1FLOP +Two FLOPs ops = PM_VSU0_2FLOP+PM_VSU1_2FLOP +[MFLOP/s] = 1E-6*(PM_VSU0_1FLOP+PM_VSU1_1FLOP+((PM_VSU0_2FLOP+PM_VSU1_2FLOP)*2))/time +-- +Group 121 from web page http://www.ibm.com/support/knowledgecenter/en/SSFK5S_2.2.0/com.ibm.cluster.pedev.v2r2.pedev100.doc/bl7ug_power8metrics.htm diff --git a/collectors/likwid/groups/power8/FLOPS_4_8.txt b/collectors/likwid/groups/power8/FLOPS_4_8.txt new file mode 100644 index 0000000..70e600a --- /dev/null +++ b/collectors/likwid/groups/power8/FLOPS_4_8.txt @@ -0,0 +1,24 @@ +SHORT Group 122 as used in IBM Parallel Environment Developer Edition + +EVENTSET +PMC0 PM_VSU0_4FLOP +PMC1 PM_VSU1_4FLOP +PMC2 PM_VSU0_8FLOP +PMC3 PM_VSU1_8FLOP +PMC4 PM_RUN_INST_CMPL +PMC5 PM_RUN_CYC + +METRICS +CPI PMC5/PMC4 +Four FLOPs ops PMC0+PMC1 +Eight FLOPs ops PMC2+PMC3 +MFLOP/s 1E-6*(((PMC0+PMC1)*4.0)+((PMC2+PMC3)*8.0))/time + +LONG +Formulas: +CPI = PM_RUN_CYC/PM_RUN_INST_CMPL +Four FLOPs ops = PM_VSU0_4FLOP+PM_VSU1_4FLOP +Eight FLOPs ops = PM_VSU0_8FLOP+PM_VSU1_8FLOP +MFLOP/s = 1E-6*(((PM_VSU0_4FLOP+PM_VSU1_4FLOP)*4.0)+((PM_VSU0_8FLOP+PM_VSU1_8FLOP)*8.0))/time +-- +Group 122 from web page http://www.ibm.com/support/knowledgecenter/en/SSFK5S_2.2.0/com.ibm.cluster.pedev.v2r2.pedev100.doc/bl7ug_power8metrics.htm diff --git a/collectors/likwid/groups/power8/FLOPS_DP.txt b/collectors/likwid/groups/power8/FLOPS_DP.txt new file mode 100644 index 0000000..8c3bfdf --- /dev/null +++ b/collectors/likwid/groups/power8/FLOPS_DP.txt @@ -0,0 +1,27 @@ +SHORT Double Precision MFlops/s + +EVENTSET +PMC0 PM_VSU0_DP_2FLOP +PMC1 PM_VSU0_DP_FMA +PMC2 PM_VSU0_DP_FSQRT_FDIV +PMC3 PM_VSU0_SCALAR_DP_ISSUED +PMC4 PM_RUN_INST_CMPL +PMC5 PM_RUN_CYC + +METRICS +Runtime (RDTSC) [s] time +CPI PMC5/PMC4 +DP [MFLOP/s] 1.0E-06*((PMC0*2.0)+PMC2+(PMC1*4.0))/time +DP VSX [MFLOP/s] 1.0E-06*((PMC1*4.0)+(PMC0*2.0))/time +Packed [MUOPS/s] 1.0E-06*(PMC1)/time +Scalar [MUOPS/s] 1.0E-06*(PMC0+PMC2)/time + +LONG +Formulas: +CPI = PM_RUN_CYC/PM_RUN_INST_CMPL +DP [MFLOP/s] = 1.0E-06*(PM_VSU0_SCALAR_DP_ISSUED+PM_VSU1_SCALAR_DP_ISSUED+(PM_VSU0_VECTOR_DP_ISSUED+PM_VSU1_VECTOR_DP_ISSUED)*4)/runtime +DP VSX [MFLOP/s] = 1.0E-06*((PM_VSU0_VECTOR_DP_ISSUED+PM_VSU1_VECTOR_DP_ISSUED)*4)/runtime +Packed [MUOPS/s] = 1.0E-06*(PM_VSU0_VECTOR_DP_ISSUED+PM_VSU1_VECTOR_DP_ISSUED)/runtime +Scalar [MUOPS/s] = 1.0E-06*(PM_VSU0_SCALAR_DP_ISSUED+PM_VSU1_SCALAR_DP_ISSUED)/runtime +-- + diff --git a/collectors/likwid/groups/power8/FLOPS_DP2.txt b/collectors/likwid/groups/power8/FLOPS_DP2.txt new file mode 100644 index 0000000..69ca9e2 --- /dev/null +++ b/collectors/likwid/groups/power8/FLOPS_DP2.txt @@ -0,0 +1,27 @@ +SHORT Double Precision MFlops/s + +EVENTSET +PMC0 PM_VSU1_DP_2FLOP +PMC1 PM_VSU1_DP_FMA +PMC2 PM_VSU1_DP_FSQRT_FDIV +PMC3 PM_VSU1_SCALAR_DP_ISSUED +PMC4 PM_RUN_INST_CMPL +PMC5 PM_RUN_CYC + +METRICS +Runtime (RDTSC) [s] time +CPI PMC5/PMC4 +DP [MFLOP/s] 1.0E-06*(PMC0+PMC2+(PMC1)*4.0)/time +DP VSX [MFLOP/s] 1.0E-06*((PMC1)*4.0)/time +Packed [MUOPS/s] 1.0E-06*(PMC1)/time +Scalar [MUOPS/s] 1.0E-06*(PMC0+PMC2)/time + +LONG +Formulas: +CPI = PM_RUN_CYC/PM_RUN_INST_CMPL +DP [MFLOP/s] = 1.0E-06*(PM_VSU0_SCALAR_DP_ISSUED+PM_VSU1_SCALAR_DP_ISSUED+(PM_VSU0_VECTOR_DP_ISSUED+PM_VSU1_VECTOR_DP_ISSUED)*4)/runtime +DP VSX [MFLOP/s] = 1.0E-06*((PM_VSU0_VECTOR_DP_ISSUED+PM_VSU1_VECTOR_DP_ISSUED)*4)/runtime +Packed [MUOPS/s] = 1.0E-06*(PM_VSU0_VECTOR_DP_ISSUED+PM_VSU1_VECTOR_DP_ISSUED)/runtime +Scalar [MUOPS/s] = 1.0E-06*(PM_VSU0_SCALAR_DP_ISSUED+PM_VSU1_SCALAR_DP_ISSUED)/runtime +-- + diff --git a/collectors/likwid/groups/power8/FLOPS_FMA.txt b/collectors/likwid/groups/power8/FLOPS_FMA.txt new file mode 100644 index 0000000..8bf5234 --- /dev/null +++ b/collectors/likwid/groups/power8/FLOPS_FMA.txt @@ -0,0 +1,28 @@ +SHORT Group 124 as used in IBM Parallel Environment Developer Edition + +EVENTSET +PMC0 PM_VSU0_DP_FMA +PMC1 PM_VSU1_DP_FMA +PMC2 PM_VSU0_FMA +PMC3 PM_VSU1_FMA +PMC4 PM_RUN_INST_CMPL +PMC5 PM_RUN_CYC + +METRICS +CPI PMC5/PMC4 +DP FMAs PMC0+PMC1 +Scalar FMAs PMC2+PMC3 +DP FMA [MFLOP/s] 1E-6*(PMC0+PMC1)*4.0/time +Scalar FMA [MFLOP/s] 1E-6*(PMC2+PMC3)*2.0/time +[MFLOP/s] 1E-6*(((PMC0+PMC1)*4.0)+((PMC2+PMC3)*2.0))/time + +LONG +Formulas: +CPI = PM_RUN_CYC/PM_RUN_INST_CMPL +DP FMAs = PM_VSU0_DP_FMA+PM_VSU1_DP_FMA +Scalar FMAs = PM_VSU0_FMA+PM_VSU1_FMA +DP FMA [MFLOP/s] = 1E-6*(PM_VSU0_DP_FMA+PM_VSU1_DP_FMA)*4.0/runtime +Scalar FMA [MFLOP/s] = 1E-6*(PM_VSU0_FMA+PM_VSU1_FMA)*2.0/runtime +[MFLOP/s] = 1E-6*(((PM_VSU0_DP_FMA+PM_VSU1_DP_FMA)*4.0)+((PM_VSU0_FMA+PM_VSU1_FMA)*2.0))/runtime +-- +Group 124 from web page http://www.ibm.com/support/knowledgecenter/en/SSFK5S_2.2.0/com.ibm.cluster.pedev.v2r2.pedev100.doc/bl7ug_power8metrics.htm diff --git a/collectors/likwid/groups/power8/FLOPS_SP.txt b/collectors/likwid/groups/power8/FLOPS_SP.txt new file mode 100644 index 0000000..19bcd5c --- /dev/null +++ b/collectors/likwid/groups/power8/FLOPS_SP.txt @@ -0,0 +1,27 @@ +SHORT Double Precision MFlops/s + +EVENTSET +PMC0 PM_VSU0_SINGLE +PMC1 PM_VSU0_VECTOR_SP_ISSUED +PMC2 PM_VSU1_SINGLE +PMC3 PM_VSU1_VECTOR_SP_ISSUED +PMC4 PM_RUN_INST_CMPL +PMC5 PM_RUN_CYC + +METRICS +Runtime (RDTSC) [s] time +CPI PMC5/PMC4 +SP [MFLOP/s] 1.0E-06*(((PMC0-PMC1)+(PMC2-PMC3))*4.0+(PMC1+PMC3)*8.0)/time +SP VSX [MFLOP/s] 1.0E-06*((PMC1+PMC3)*8.0)/time +Packed [MUOPS/s] 1.0E-06*(PMC1+PMC3)/time +Scalar [MUOPS/s] 1.0E-06*(PMC0+PMC2)/time + +LONG +Formulas: +CPI = PM_RUN_CYC/PM_RUN_INST_CMPL +SP [MFLOP/s] = 1.0E-06*(PM_VSU0_SINGLE+PM_VSU1_SINGLE+(PM_VSU0_VECTOR_SP_ISSUED+PM_VSU1_VECTOR_SP_ISSUED)*8)/runtime +SP VSX [MFLOP/s] = 1.0E-06*((PM_VSU0_VECTOR_SP_ISSUED+PM_VSU1_VECTOR_SP_ISSUED)*8)/runtime +Packed [MUOPS/s] = 1.0E-06*(PM_VSU0_VECTOR_SP_ISSUED+PM_VSU1_VECTOR_SP_ISSUED)/runtime +Scalar [MUOPS/s] = 1.0E-06*(PM_VSU0_SINGLE+PM_VSU1_SINGLE)/runtime +-- + diff --git a/collectors/likwid/groups/power8/FLOPS_VSU0.txt b/collectors/likwid/groups/power8/FLOPS_VSU0.txt new file mode 100644 index 0000000..fa94626 --- /dev/null +++ b/collectors/likwid/groups/power8/FLOPS_VSU0.txt @@ -0,0 +1,23 @@ +SHORT Double Precision MFlops/s performed by VSU pipe 0 + +EVENTSET +PMC0 PM_VSU0_DP_2FLOP +PMC1 PM_VSU0_DP_FMA +PMC2 PM_VSU0_DP_FSQRT_FDIV +PMC3 PM_VSU0_1FLOP +PMC4 PM_RUN_INST_CMPL +PMC5 PM_RUN_CYC + +METRICS +Runtime (RDTSC) [s] time +CPI PMC5/PMC4 +[MFLOP/s] 1.0E-06*((PMC0*2.0)+(PMC2*8.0)+(PMC1*4.0)+PMC3)/time +VSX [MFLOP/s] 1.0E-06*(PMC1*4.0)/time + +LONG +Formulas: +CPI = PM_RUN_CYC/PM_RUN_INST_CMPL +[MFLOP/s] = 1.0E-06*(PM_VSU0_SCALAR_DP_ISSUED+PM_VSU0_SCALAR_DP_ISSUED+(PM_VSU0_VECTOR_DP_ISSUED+PM_VSU0_VECTOR_DP_ISSUED)*4)/runtime +VSX [MFLOP/s] = 1.0E-06*((PM_VSU0_VECTOR_DP_ISSUED+PM_VSU1_VECTOR_DP_ISSUED)*4)/runtime +-- + diff --git a/collectors/likwid/groups/power8/FLOPS_VSU1.txt b/collectors/likwid/groups/power8/FLOPS_VSU1.txt new file mode 100644 index 0000000..617ab88 --- /dev/null +++ b/collectors/likwid/groups/power8/FLOPS_VSU1.txt @@ -0,0 +1,22 @@ +SHORT Double Precision MFlops/s performed by VSU pipe 1 + +EVENTSET +PMC0 PM_VSU1_DP_2FLOP +PMC1 PM_VSU1_DP_FMA +PMC2 PM_VSU1_DP_FSQRT_FDIV +PMC3 PM_VSU1_1FLOP +PMC4 PM_RUN_INST_CMPL +PMC5 PM_RUN_CYC + +METRICS +Runtime (RDTSC) [s] time +CPI PMC5/PMC4 +[MFLOP/s] 1.0E-06*((PMC0*2.0)+(PMC2*8.0)+(PMC1*4.0)+PMC3)/time +VSX [MFLOP/s] 1.0E-06*(PMC1*4.0)/time + +LONG +Formulas: +CPI = PM_RUN_CYC/PM_RUN_INST_CMPL +[MFLOP/s] = 1.0E-06*(PM_VSU1_SCALAR_DP_ISSUED+PM_VSU1_SCALAR_DP_ISSUED+(PM_VSU1_VECTOR_DP_ISSUED+PM_VSU1_VECTOR_DP_ISSUED)*4)/runtime +VSX [MFLOP/s] = 1.0E-06*((PM_VSU0_VECTOR_DP_ISSUED+PM_VSU1_VECTOR_DP_ISSUED)*4)/runtime +-- diff --git a/collectors/likwid/groups/power8/FLOPS_VSX.txt b/collectors/likwid/groups/power8/FLOPS_VSX.txt new file mode 100644 index 0000000..063ad0c --- /dev/null +++ b/collectors/likwid/groups/power8/FLOPS_VSX.txt @@ -0,0 +1,29 @@ +SHORT Vectorized MFlops/s + +EVENTSET +PMC0 PM_VSU0_VECTOR_DP_ISSUED +PMC1 PM_VSU1_VECTOR_DP_ISSUED +PMC2 PM_VSU0_VECTOR_SP_ISSUED +PMC3 PM_VSU1_VECTOR_SP_ISSUED +PMC4 PM_RUN_INST_CMPL +PMC5 PM_RUN_CYC + +METRICS +Runtime (RDTSC) [s] time +CPI PMC5/PMC4 +[MFLOP/s] 1.0E-06*((PMC0+PMC1)*4.0+(PMC2+PMC3)*8.0)/time +DP [MFLOP/s] 1.0E-06*((PMC0+PMC1)*4.0)/time +SP [MFLOP/s] 1.0E-06*((PMC2+PMC3)*8.0)/time +DP [MUOPS/s] 1.0E-06*(PMC0+PMC1)/time +SP [MUOPS/s] 1.0E-06*(PMC2+PMC3)/time + +LONG +Formulas: +CPI = PM_RUN_CYC/PM_RUN_INST_CMPL +[MFLOP/s] = 1.0E-06*((PM_VSU0_VECTOR_DP_ISSUED+PM_VSU1_VECTOR_DP_ISSUED)*4.0+(PM_VSU0_VECTOR_SP_ISSUED+PM_VSU1_VECTOR_SP_ISSUED)*8.0)/runtime +DP [MFLOP/s] = 1.0E-06*((PM_VSU0_VECTOR_DP_ISSUED+PM_VSU1_VECTOR_DP_ISSUED)*4.0)/runtime +SP [MFLOP/s] = 1.0E-06*((PM_VSU0_VECTOR_SP_ISSUED+PM_VSU1_VECTOR_SP_ISSUED)*8.0)/runtime +DP [MUOPS/s] = 1.0E-06*(PM_VSU0_VECTOR_DP_ISSUED+PM_VSU1_VECTOR_DP_ISSUED)/runtime +SP [MUOPS/s] = 1.0E-06*(PM_VSU0_VECTOR_SP_ISSUED+PM_VSU1_VECTOR_SP_ISSUED)/runtime +-- + diff --git a/collectors/likwid/groups/power8/ICACHE.txt b/collectors/likwid/groups/power8/ICACHE.txt new file mode 100644 index 0000000..7a07fd4 --- /dev/null +++ b/collectors/likwid/groups/power8/ICACHE.txt @@ -0,0 +1,22 @@ +SHORT Instruction cache miss rate/ratio + +EVENTSET +PMC0 PM_INST_FROM_L1 +PMC1 PM_L1_ICACHE_MISS +PMC4 PM_RUN_INST_CMPL +PMC5 PM_RUN_CYC + +METRICS +Runtime (RDTSC) [s] time +CPI PMC5/PMC4 +L1I request rate PMC0/PMC4 +L1I miss rate PMC1/PMC4 +L1I miss ratio PMC1/PMC0 + +LONG +Formulas: +L1I request rate = ICACHE_ACCESSES / INSTR_RETIRED_ANY +L1I miss rate = ICACHE_MISSES / INSTR_RETIRED_ANY +L1I miss ratio = ICACHE_MISSES / ICACHE_ACCESSES +- +This group measures some L1 instruction cache metrics. diff --git a/collectors/likwid/groups/power8/L1.txt b/collectors/likwid/groups/power8/L1.txt new file mode 100644 index 0000000..19dc36e --- /dev/null +++ b/collectors/likwid/groups/power8/L1.txt @@ -0,0 +1,33 @@ +SHORT L2 cache bandwidth in MBytes/s + +EVENTSET +PMC0 PM_LD_REF_L1 +PMC1 PM_ST_CMPL +PMC2 PM_LSU_L1_PREF +PMC4 PM_RUN_INST_CMPL +PMC5 PM_RUN_CYC + + +METRICS +Runtime (RDTSC) [s] time +CPI PMC5/PMC4 +L2D load bandwidth [MBytes/s] 1.0E-06*((PMC0+PMC2)/2)*64.0/time +L2D load data volume [GBytes] 1.0E-09*((PMC0+PMC2)/2)*64.0 +L2D store bandwidth [MBytes/s] 1.0E-06*((PMC1/2))*64.0/time +L2D store data volume [GBytes] 1.0E-09*((PMC1/2))*64.0 +L2 bandwidth [MBytes/s] 1.0E-06*((PMC1+PMC0+PMC2)/2)*64.0/time +L2 data volume [GBytes] 1.0E-09*((PMC1+PMC0+PMC2)/2)*64.0 + +LONG +Formulas: +CPI = PM_RUN_CYC/PM_RUN_INST_CMPL +L2D load bandwidth [MBytes/s] = 1.0E-06*(PM_DATA_FROM_L2/2)*128.0/time +L2D load data volume [GBytes] = 1.0E-09*(PM_DATA_FROM_L2/2)*128.0 +L2D store bandwidth [MBytes/s] = 1.0E-06*(PM_ST_MISS_L1)*128.0/time +L2D store data volume [GBytes] = 1.0E-09*(PM_ST_MISS_L1)*128.0 +L2 bandwidth [MBytes/s] = 1.0E-06*(PM_DATA_FROM_L2/2 + PM_ST_MISS_L1)*128.0/time +L2 data volume [GBytes] = 1.0E-09*(PM_DATA_FROM_L2/2 + PM_ST_MISS_L1)*128.0 +- +Profiling group to measure L2 cache bandwidth. The bandwidth is computed by the +number of cacheline loaded from the L2 to the L1 data cache. There is currently no +event to get the evicted data volume. diff --git a/collectors/likwid/groups/power8/L2.txt b/collectors/likwid/groups/power8/L2.txt new file mode 100644 index 0000000..d5af584 --- /dev/null +++ b/collectors/likwid/groups/power8/L2.txt @@ -0,0 +1,32 @@ +SHORT L2 cache bandwidth in MBytes/s + +EVENTSET +PMC0 PM_L2_ST +PMC2 PM_LD_MISS_L1 +PMC4 PM_RUN_INST_CMPL +PMC5 PM_RUN_CYC + + +METRICS +Runtime (RDTSC) [s] time +CPI PMC5/PMC4 +L2D load bandwidth [MBytes/s] 1.0E-06*(PMC2/2)*128.0/time +L2D load data volume [GBytes] 1.0E-09*(PMC2/2)*128.0 +L2D store bandwidth [MBytes/s] 1.0E-06*(PMC0/2)*128.0/time +L2D store data volume [GBytes] 1.0E-09*(PMC0/2)*128.0 +L2 bandwidth [MBytes/s] 1.0E-06*((PMC0+PMC2)/2)*128.0/time +L2 data volume [GBytes] 1.0E-09*((PMC0+PMC2)/2)*128.0 + +LONG +Formulas: +CPI = PM_RUN_CYC/PM_RUN_INST_CMPL +L2D load bandwidth [MBytes/s] = 1.0E-06*(PM_DATA_FROM_L2/2)*128.0/time +L2D load data volume [GBytes] = 1.0E-09*(PM_DATA_FROM_L2/2)*128.0 +L2D store bandwidth [MBytes/s] = 1.0E-06*(PM_ST_CMPL/2)*128.0/time +L2D store data volume [GBytes] = 1.0E-09*(PM_ST_CMPL/2)*128.0 +L2 bandwidth [MBytes/s] = 1.0E-06*((PM_DATA_FROM_L2 + PM_ST_CMPL))*128.0/time +L2 data volume [GBytes] = 1.0E-09*((PM_DATA_FROM_L2 + PM_ST_CMPL))*128.0 +- +Profiling group to measure L2 cache bandwidth. The bandwidth is computed by the +number of cacheline loaded from the L2 to the L1 data cache. There is currently no +event to get the evicted data volume. diff --git a/collectors/likwid/groups/power8/L2CACHE.txt b/collectors/likwid/groups/power8/L2CACHE.txt new file mode 100644 index 0000000..47bcedd --- /dev/null +++ b/collectors/likwid/groups/power8/L2CACHE.txt @@ -0,0 +1,40 @@ +SHORT L2 cache miss rate/ratio + +EVENTSET +PMC0 PM_L2_ST_MISS +PMC1 PM_L2_LD_MISS +PMC2 PM_L2_LD_DISP +PMC3 PM_L2_ST_DISP +PMC4 PM_RUN_INST_CMPL +PMC5 PM_RUN_CYC + + +METRICS +Runtime (RDTSC) [s] time +CPI PMC5/PMC4 +L2 request rate = (PMC2+PMC3)/PMC4 +L2 miss rate = (PMC0+PMC1)/PMC4 +L2 miss ratio = (PMC0+PMC1)/(PMC2+PMC3) + +LONG +Formulas: +L2 request rate = (PM_L2_LD_DISP+PM_L2_ST_DISP)/PM_RUN_INST_CMPL +L2 miss rate = (PM_L2_LD_MISS+PM_L2_ST_MISS)/PM_RUN_INST_CMPL +L2 miss ratio = (PM_L2_LD_MISS+PM_L2_ST_MISS)/(PM_L2_LD_DISP+PM_L2_ST_DISP) +L2 load request rate = PM_L2_LD_DISP/PM_RUN_INST_CMPL +L2 store request rate = PM_L2_ST_DISP/PM_RUN_INST_CMPL +L2 load miss rate = PM_L2_LD_MISS/PM_RUN_INST_CMPL +L2 store miss rate = PM_L2_ST_DISP/PM_RUN_INST_CMPL +L2 load miss ratio = PM_L2_LD_MISS/(PM_L2_LD_DISP+PM_L2_ST_DISP) +L2 store miss ratio = PM_L2_ST_MISS/(PM_L2_LD_DISP+PM_L2_ST_DISP) +- +This group measures the locality of your data accesses with regard to the +L2 Cache. L2 request rate tells you how data intensive your code is +or how many Data accesses you have in average per instruction. +The L2 miss rate gives a measure how often it was necessary to get +cachelines from memory. And finally L2 miss ratio tells you how many of your +memory references required a cacheline to be loaded from a higher level. +While the Data cache miss rate might be given by your algorithm you should +try to get Data cache miss ratio as low as possible by increasing your cache reuse. + + diff --git a/collectors/likwid/groups/power8/L3.txt b/collectors/likwid/groups/power8/L3.txt new file mode 100644 index 0000000..0737c44 --- /dev/null +++ b/collectors/likwid/groups/power8/L3.txt @@ -0,0 +1,31 @@ +SHORT L3 cache bandwidth in MBytes/s + +EVENTSET +PMC0 PM_L3_LD_PREF +PMC3 PM_DATA_FROM_L3 +PMC4 PM_RUN_INST_CMPL +PMC5 PM_RUN_CYC + + +METRICS +Runtime (RDTSC) [s] time +CPI PMC5/PMC4 +L3D load bandwidth [MBytes/s] 1.0E-06*(PMC3+(PMC0-PMC3))*128.0/time +L3D load data volume [GBytes] 1.0E-09*(PMC3+(PMC0-PMC3))*128.0 +L3 bandwidth [MBytes/s] 1.0E-06*(PMC3+(PMC0-PMC3))*128.0/time +L3 data volume [GBytes] 1.0E-09*(PMC3+(PMC0-PMC3))*128.0 +Loads from local L3 per cycle 100.0*(PMC3+(PMC0-PMC3))/PMC5 + +LONG +Formulas: +CPI = PM_RUN_CYC/PM_RUN_INST_CMPL +L3D load bandwidth [MBytes/s] = 1.0E-06*(PM_DATA_FROM_L3)*128.0/time +L3D load data volume [GBytes] = 1.0E-09*(PM_DATA_FROM_L3)*128.0 +L3D evict bandwidth [MBytes/s] = 1.0E-06*(PM_L2_CASTOUT_MOD)*128.0/time +L3D evict data volume [GBytes] = 1.0E-09*(PM_L2_CASTOUT_MOD)*128.0 +L3 bandwidth [MBytes/s] = 1.0E-06*(PM_DATA_FROM_L3+PM_L2_CASTOUT_MOD)*128.0/time +L3 data volume [GBytes] = 1.0E-09*(PM_DATA_FROM_L3+PM_L2_CASTOUT_MOD)*128.0 +- +Profiling group to measure L3 cache bandwidth. The bandwidth is computed by the +number of cacheline loaded from the L3 to the L2 data cache. There is currently no +event to get the evicted data volume. diff --git a/collectors/likwid/groups/power8/MEM.txt b/collectors/likwid/groups/power8/MEM.txt new file mode 100644 index 0000000..4831c80 --- /dev/null +++ b/collectors/likwid/groups/power8/MEM.txt @@ -0,0 +1,30 @@ +SHORT Main memory bandwidth in MBytes/s + +EVENTSET +PMC0 PM_L3_CO_MEPF +PMC1 PM_DATA_ALL_FROM_MEMORY +PMC3 PM_L3_PF_ON_CHIP_MEM +PMC4 PM_RUN_INST_CMPL +PMC5 PM_RUN_CYC + +METRICS +Runtime (RDTSC) [s] time +CPI PMC5/PMC4 +Memory load bandwidth [MBytes/s] 1.0E-06*(PMC1+PMC3)*128.0/time +Memory load data volume [GBytes] 1.0E-09*(PMC1+PMC3)*128.0 +Memory evict bandwidth [MBytes/s] 1.0E-06*(PMC0)*128.0/time +Memory evict data volume [GBytes] 1.0E-09*(PMC0)*128.0 +Memory bandwidth [MBytes/s] 1.0E-06*(PMC1+PMC3+PMC0)*128.0/time +Memory data volume [GBytes] 1.0E-09*(PMC1+PMC3+PMC0)*128.0 + +LONG +Formulas: +CPI = PM_RUN_CYC / PM_RUN_INST_CMPL +Memory load bandwidth [MBytes/s] = 1.0E-06* (PM_DATA_ALL_FROM_MEMORY)*128/time +Memory load data volume [GBytes] = 1.0E-09* (PM_DATA_ALL_FROM_MEMORY)*128 +Memory evict bandwidth [MBytes/s] = 1.0E-06* (PM_MEM_CO)*128/time +Memory evict data volume [GBytes] = 1.0E-09* (PM_MEM_CO)*128 +Memory bandwidth [MBytes/s] = 1.0E-06* (PM_DATA_ALL_FROM_MEMORY+PM_MEM_CO)*128/time +Memory data volume [GBytes] = 1.0E-09* (PM_DATA_ALL_FROM_MEMORY+PM_MEM_CO)*128 +-- +This group uses the core-local events to measure data traffic from memory. diff --git a/collectors/likwid/groups/power8/NUMA.txt b/collectors/likwid/groups/power8/NUMA.txt new file mode 100644 index 0000000..e2a6e71 --- /dev/null +++ b/collectors/likwid/groups/power8/NUMA.txt @@ -0,0 +1,29 @@ +SHORT Memory bandwidth in MBytes/s for local and remote memory + +EVENTSET +PMC1 PM_DATA_ALL_FROM_LMEM +PMC3 PM_DATA_ALL_FROM_DMEM +PMC4 PM_RUN_INST_CMPL +PMC5 PM_RUN_CYC + +METRICS +Runtime (RDTSC) [s] time +CPI PMC5/PMC4 +Local bandwidth [MBytes/s] 1.0E-06*(PMC1)*128.0/time +Local data volume [GBytes] 1.0E-09*(PMC1)*128.0 +Remote bandwidth [MBytes/s] 1.0E-06*(PMC3)*128.0/time +Remote data volume [GBytes] 1.0E-09*(PMC3)*128.0 +Memory load bandwidth [MBytes/s] 1.0E-06*(PMC1+PMC3)*128.0/time +Memory load data volume [GBytes] 1.0E-09*(PMC1+PMC3)*128.0 + +LONG +Formulas: +CPI = PM_RUN_CYC / PM_RUN_INST_CMPL +Memory load bandwidth [MBytes/s] = 1.0E-06* (PM_DATA_ALL_FROM_MEMORY)*128/time +Memory load data volume [GBytes] = 1.0E-09* (PM_DATA_ALL_FROM_MEMORY)*128 +Memory evict bandwidth [MBytes/s] = 1.0E-06* (PM_MEM_CO)*128/time +Memory evict data volume [GBytes] = 1.0E-09* (PM_MEM_CO)*128 +Memory bandwidth [MBytes/s] = 1.0E-06* (PM_DATA_ALL_FROM_MEMORY+PM_MEM_CO)*128/time +Memory data volume [GBytes] = 1.0E-09* (PM_DATA_ALL_FROM_MEMORY+PM_MEM_CO)*128 +-- +This group measures the NUMA traffic by separating local from remote memory data transfers. diff --git a/collectors/likwid/groups/power8/STALLS1.txt b/collectors/likwid/groups/power8/STALLS1.txt new file mode 100644 index 0000000..6acf949 --- /dev/null +++ b/collectors/likwid/groups/power8/STALLS1.txt @@ -0,0 +1,33 @@ +SHORT Completion stalls (group 1) + +EVENTSET +PMC0 PM_CMPLU_STALL_THRD +PMC1 PM_CMPLU_STALL_DCACHE_MISS +PMC2 PM_CMPLU_STALL_COQ_FULL +PMC3 PM_CMPLU_STALL +PMC4 PM_RUN_INST_CMPL +PMC5 PM_RUN_CYC + +METRICS +Runtime time +CPI PMC5/PMC4 +Completion stall cycles PMC3 +Stall cycles by thread conflict PMC0 +Stall ratio by thread conflict [%] PMC0/PMC3*100.0 +Stall cycles by d-cache miss PMC1 +Stall ratio by d-cache miss [%] PMC1/PMC3*100.0 +Stall cycles by full castout queue PMC2 +Stall ratio by full castout queue [%] PMC2/PMC3*100.0 + + +LONG +Formulas: +CPI = PM_RUN_CYC / PM_RUN_INST_CMPL +Completion stall cycles = PM_CMPLU_STALL +Stall cycles by thread conflict = PM_CMPLU_STALL_THRD +Stall ratio by thread conflict [%] = PM_CMPLU_STALL_THRD/PM_CMPLU_STALL*100 +Stall cycles by d-cache miss = PM_CMPLU_STALL_DCACHE_MISS +Stall ratio by d-cache miss [%] = PM_CMPLU_STALL_DCACHE_MISS/PM_CMPLU_STALL*100 +Stall cycles by full castout queue = PM_CMPLU_STALL_COQ_FULL +Stall ratio by full castout queue [%] = PM_CMPLU_STALL_COQ_FULL/PM_CMPLU_STALL*100 +-- diff --git a/collectors/likwid/groups/power8/STALLS2.txt b/collectors/likwid/groups/power8/STALLS2.txt new file mode 100644 index 0000000..6329624 --- /dev/null +++ b/collectors/likwid/groups/power8/STALLS2.txt @@ -0,0 +1,32 @@ +SHORT Completion stalls (group 2) + +EVENTSET +PMC0 PM_CMPLU_STALL +PMC1 PM_CMPLU_STALL_LSU +PMC2 PM_CMPLU_STALL_FLUSH +PMC3 PM_CMPLU_STALL_BRU +PMC4 PM_RUN_INST_CMPL +PMC5 PM_RUN_CYC + +METRICS +CPI PMC5/PMC4 +Stall cycles PMC0 +Stall cycles by load/store unit PMC1 +Stall ratio by load/store unit [%] PMC1/PMC0*100.0 +Stall cycles by pipeline flush PMC2 +Stall ratio by pipeline flush [%] PMC2/PMC0*100.0 +Stall cycles by branch unit PMC3 +Stall ratio by branch unit [%] PMC3/PMC0*100.0 + + +LONG +Formulas: +CPI = PM_RUN_CYC / PM_RUN_INST_CMPL +Stall cycles = PM_CMPLU_STALL +Stall cycles by load/store unit = PM_CMPLU_STALL_LSU +Stall ratio by load/store unit [%] = PM_CMPLU_STALL_LSU/PM_CMPLU_STALL*100.0 +Stall cycles by pipeline flush = PM_CMPLU_STALL_FLUSH +Stall ratio by pipeline flush [%] = PM_CMPLU_STALL_FLUSH/PM_CMPLU_STALL*100.0 +Stall cycles by branch unit = PM_CMPLU_STALL_BRU +Stall ratio by branch unit [%] = PM_CMPLU_STALL_BRU/PM_CMPLU_STALL*100.0 +-- diff --git a/collectors/likwid/groups/power8/TLB_DATA.txt b/collectors/likwid/groups/power8/TLB_DATA.txt new file mode 100644 index 0000000..c7df459 --- /dev/null +++ b/collectors/likwid/groups/power8/TLB_DATA.txt @@ -0,0 +1,37 @@ +SHORT L1 Data TLB miss rate/ratio + +EVENTSET +PMC0 PM_DTLB_MISS_16G +PMC1 PM_DTLB_MISS_4K +PMC2 PM_DTLB_MISS_64K +PMC3 PM_DTLB_MISS_16M +PMC4 PM_RUN_INST_CMPL +PMC5 PM_RUN_CYC + +METRICS +Runtime (RDTSC) [s] time +CPI PMC5/PMC4 +L1 DTLB 4K misses PMC1 +L1 DTLB 4K miss rate PMC1/PMC4 +L1 DTLB 64K misses PMC2 +L1 DTLB 64K miss rate PMC2/PMC4 +L1 DTLB 16M misses PMC3 +L1 DTLB 16M miss rate PMC3/PMC4 +L1 DTLB 16G misses PMC0 +L1 DTLB 16G miss rate PMC0/PMC4 + +LONG +Formulas: +CPI = PM_RUN_CYC / PM_RUN_INST_CMPL +L1 DTLB 4K misses = PM_DTLB_MISS_4K +L1 DTLB 4K miss rate = PM_DTLB_MISS_4K/PM_RUN_INST_CMPL +L1 DTLB 64K misses = PM_DTLB_MISS_64K +L1 DTLB 64K miss rate = PM_DTLB_MISS_64K/PM_RUN_INST_CMPL +L1 DTLB 16M misses = PM_DTLB_MISS_16M +L1 DTLB 16M miss rate = PM_DTLB_MISS_16M/PM_RUN_INST_CMPL +L1 DTLB 16G misses = PM_DTLB_MISS_16G +L1 DTLB 16G miss rate = PM_DTLB_MISS_16G/PM_RUN_INST_CMPL +-- +The DTLB load and store miss rates gives a measure how often a TLB miss occured +per instruction. + diff --git a/collectors/likwid/groups/power8/TLB_INSTR.txt b/collectors/likwid/groups/power8/TLB_INSTR.txt new file mode 100644 index 0000000..3f8b79c --- /dev/null +++ b/collectors/likwid/groups/power8/TLB_INSTR.txt @@ -0,0 +1,21 @@ +SHORT L1 Instruction TLB miss rate/ratio + +EVENTSET +PMC2 PM_ITLB_MISS +PMC4 PM_RUN_INST_CMPL +PMC5 PM_RUN_CYC + +METRICS +Runtime (RDTSC) [s] time +CPI PMC5/PMC4 +L1 ITLB misses PMC2 +L1 ITLB miss rate PMC2/PMC4 + +LONG +Formulas: +CPI = PM_RUN_CYC / PM_RUN_INST_CMPL +L1 ITLB misses = PM_ITLB_MISS +L1 ITLB miss rate = PM_ITLB_MISS/PM_RUN_INST_CMPL +-- +The ITLB miss rate gives a measure how often a TLB miss occured per instruction. + diff --git a/collectors/likwid/groups/power8/USEFUL.txt b/collectors/likwid/groups/power8/USEFUL.txt new file mode 100644 index 0000000..0b5fc8f --- /dev/null +++ b/collectors/likwid/groups/power8/USEFUL.txt @@ -0,0 +1,24 @@ +SHORT Rate of useful instructions + +EVENTSET +PMC0 PM_IOPS_CMPL +PMC1 PM_INST_DISP +PMC2 PM_IOPS_DISP +PMC4 PM_RUN_INST_CMPL +PMC5 PM_RUN_CYC + +METRICS +CPI PMC5/PMC4 +Useful instr. rate PMC4/PMC1*100.0 +Useful uops rate PMC0/PMC2*100.0 + + +LONG +Formulas: +CPI = PM_RUN_CYC / PM_RUN_INST_CMPL +Useful instr. rate = PM_RUN_INST_CMPL/PM_INST_DISP*100.0 +Useful uops rate = PM_IOPS_CMPL/PM_IOPS_DISP*100.0 +-- +This groups measures how many of the dispatched instructions and internal operations (uops) are +acutally completed. These metrics show the speculatively dispatches instructions compared to the +completed instructions. diff --git a/collectors/likwid/groups/power9/BRANCH.txt b/collectors/likwid/groups/power9/BRANCH.txt new file mode 100644 index 0000000..1f6dd0d --- /dev/null +++ b/collectors/likwid/groups/power9/BRANCH.txt @@ -0,0 +1,30 @@ +SHORT Branch prediction miss rate/ratio + +EVENTSET +PMC1 PM_BR_PRED +PMC2 PM_IOPS_CMPL +PMC3 PM_BR_MPRED_CMPL +PMC4 PM_RUN_INST_CMPL +PMC5 PM_RUN_CYC + +METRICS +Runtime (RDTSC) [s] time +CPI PMC5/PMC4 +Branch rate (PMC1)/PMC4 +Branch misprediction rate PMC3/PMC4 +Branch misprediction ratio PMC3/(PMC1) +Instructions per branch PMC4/(PMC1) +Operations per branch PMC2/PMC1 + +LONG +Formulas: +Branch rate = PM_BR_PRED/PM_RUN_INST_CMPL +Branch misprediction rate = PM_BR_MPRED_CMPL/PM_RUN_INST_CMPL +Branch misprediction ratio = PM_BR_MPRED_CMPL/PM_BR_PRED +Instructions per branch = PM_RUN_INST_CMPL/PM_BR_PRED +- +The rates state how often in average a branch or a mispredicted branch occured +per instruction retired in total. The Branch misprediction ratio sets directly +into relation what ratio of all branch instruction where mispredicted. +Instructions per branch is 1/Branch rate. + diff --git a/collectors/likwid/groups/power9/DATA.txt b/collectors/likwid/groups/power9/DATA.txt new file mode 100644 index 0000000..a8a7cae --- /dev/null +++ b/collectors/likwid/groups/power9/DATA.txt @@ -0,0 +1,23 @@ +SHORT Load to store ratio + +EVENTSET +PMC3 PM_LD_CMPL +PMC1 PM_ST_CMPL +PMC4 PM_RUN_INST_CMPL +PMC5 PM_RUN_CYC + +METRICS +Runtime (RDTSC) [s] time +CPI PMC5/PMC4 +Load to store ratio PMC3/PMC1 +Load rate PMC3/PMC4 +Store rate PMC1/PMC4 + +LONG +Formulas: +Load to store ratio = PM_LD_CMPL/PM_ST_CMPL +Load ratio = PM_LD_CMPL/PM_RUN_INST_CMPL +Store ratio = PM_ST_CMPL/PM_RUN_INST_CMPL +- +This is a metric to determine your load to store ratio. + diff --git a/collectors/likwid/groups/power9/FLOPS.txt b/collectors/likwid/groups/power9/FLOPS.txt new file mode 100644 index 0000000..ffaf11f --- /dev/null +++ b/collectors/likwid/groups/power9/FLOPS.txt @@ -0,0 +1,25 @@ +SHORT SP/DP scalar/vector MFlops/s + +EVENTSET +PMC3 PM_FLOP_CMPL +PMC4 PM_RUN_INST_CMPL +PMC5 PM_RUN_CYC + +METRICS +Runtime (RDTSC) [s] time +CPI PMC5/PMC4 +SP/DP [MFLOP/s] (scalar assumed) 1.0E-06*PMC3*2.0/time +SP [MFLOP/s] (vector assumed) 1.0E-06*PMC3*8.0/time +DP [MFLOP/s] (vector assumed) 1.0E-06*PMC3*4.0/time + +LONG +Formulas: +CPI = PM_RUN_CYC/PM_RUN_INST_CMPL +SP/DP [MFLOP/s] (scalar assumed) = 1.0E-06*PM_FLOP_CMPL*2.0/runtime +SP [MFLOP/s] (vector assumed) = 1.0E-06*PM_FLOP_CMPL*8.0/runtime +DP [MFLOP/s] (vector assumed) = 1.0E-06*PM_FLOP_CMPL*4.0/runtime +-- +This group counts floating-point operations. All is derived out of a +single event PM_FLOP_CMPL, so if you have mixed usage of SP or DP and +scalar and vector operations, the count won't be exact. With pure codes +the counts are pretty accurate (e.g. when using likwid-bench). diff --git a/collectors/likwid/groups/power9/FLOPS_FMA.txt b/collectors/likwid/groups/power9/FLOPS_FMA.txt new file mode 100644 index 0000000..65e9b3b --- /dev/null +++ b/collectors/likwid/groups/power9/FLOPS_FMA.txt @@ -0,0 +1,21 @@ +SHORT Floating-point operations with scalar FMA instuctions + +EVENTSET +PMC3 PM_FMA_CMPL +PMC4 PM_RUN_INST_CMPL +PMC5 PM_RUN_CYC + +METRICS +Runtime (RDTSC) [s] time +CPI PMC5/PMC4 +Scalar FMAs PMC3 +Scalar FMA [MFLOP/s] 1E-6*(PMC3)*2.0/time + +LONG +Formulas: +Scalar FMAs = PM_FMA_CMPL +Scalar FMA [MFLOP/s] = 1E-6*(PM_FMA_CMPL)*2.0/runtime +-- +This groups counts scalar FMA operations. +PM_FMA_CMPL: Two-flops instruction completed (fmadd, fnmadd, fmsub, +fnmsub). Scalar instructions only. diff --git a/collectors/likwid/groups/power9/FLOPS_VSX.txt b/collectors/likwid/groups/power9/FLOPS_VSX.txt new file mode 100644 index 0000000..594adf0 --- /dev/null +++ b/collectors/likwid/groups/power9/FLOPS_VSX.txt @@ -0,0 +1,23 @@ +SHORT Vectorized MFlops/s + +EVENTSET +PMC1 PM_VSU_FIN +PMC3 PM_VECTOR_FLOP_CMPL +PMC4 PM_RUN_INST_CMPL +PMC5 PM_RUN_CYC + +METRICS +Runtime (RDTSC) [s] time +CPI PMC5/PMC4 +SP [MFLOP/s] (assumed) 1.0E-06*(PMC3*8.0)/time +DP [MFLOP/s] (assumed) 1.0E-06*(PMC3*4.0)/time +Vector MIOPS/s 1.0E-06*(PMC1)/time + +LONG +Formulas: +CPI = PM_RUN_CYC/PM_RUN_INST_CMPL +SP [MFLOP/s] (assumed) = 1.0E-06*(PM_VECTOR_FLOP_CMPL*4)/runtime +DP [MFLOP/s] (assumed) = 1.0E-06*(PM_VECTOR_FLOP_CMPL*8)/runtime +Vector MIOPS/s = 1.0E-06*(PM_VECTOR_FLOP_CMPL)/runtime +-- +This group measures vector operations. There is no differentiation between SP and DP possible. diff --git a/collectors/likwid/groups/power9/ICACHE.txt b/collectors/likwid/groups/power9/ICACHE.txt new file mode 100644 index 0000000..7a07fd4 --- /dev/null +++ b/collectors/likwid/groups/power9/ICACHE.txt @@ -0,0 +1,22 @@ +SHORT Instruction cache miss rate/ratio + +EVENTSET +PMC0 PM_INST_FROM_L1 +PMC1 PM_L1_ICACHE_MISS +PMC4 PM_RUN_INST_CMPL +PMC5 PM_RUN_CYC + +METRICS +Runtime (RDTSC) [s] time +CPI PMC5/PMC4 +L1I request rate PMC0/PMC4 +L1I miss rate PMC1/PMC4 +L1I miss ratio PMC1/PMC0 + +LONG +Formulas: +L1I request rate = ICACHE_ACCESSES / INSTR_RETIRED_ANY +L1I miss rate = ICACHE_MISSES / INSTR_RETIRED_ANY +L1I miss ratio = ICACHE_MISSES / ICACHE_ACCESSES +- +This group measures some L1 instruction cache metrics. diff --git a/collectors/likwid/groups/power9/L2CACHE.txt b/collectors/likwid/groups/power9/L2CACHE.txt new file mode 100644 index 0000000..9873251 --- /dev/null +++ b/collectors/likwid/groups/power9/L2CACHE.txt @@ -0,0 +1,33 @@ +SHORT L2 cache miss rate/ratio + +EVENTSET +PMC1 PM_L2_LD_MISS +PMC2 PM_L2_LD_DISP +PMC3 PM_L2_ST_DISP +PMC4 PM_RUN_INST_CMPL +PMC5 PM_RUN_CYC + + +METRICS +Runtime (RDTSC) [s] time +CPI PMC5/PMC4 +L2 request rate (PMC2+PMC3)/PMC4 +L2 load miss rate PMC1/PMC4 +L2 load miss ratio PMC1/(PMC2+PMC3) + +LONG +Formulas: +L2 request rate = (PM_L2_LD_DISP+PM_L2_ST_DISP)/PM_RUN_INST_CMPL +L2 load miss rate = (PM_L2_LD_MISS)/PM_RUN_INST_CMPL +L2 load miss ratio = (PM_L2_LD_MISS)/(PM_L2_LD_DISP+PM_L2_ST_DISP) +- +This group measures the locality of your data accesses with regard to the +L2 Cache. L2 request rate tells you how data intensive your code is +or how many data accesses you have in average per instruction. +The L2 miss rate gives a measure how often it was necessary to get +cachelines from memory. And finally L2 load miss ratio tells you how many of your +memory references required a cacheline to be loaded from a higher level. +While the data cache miss rate might be given by your algorithm you should +try to get data cache miss ratio as low as possible by increasing your cache reuse. + + diff --git a/collectors/likwid/groups/power9/L2LOAD.txt b/collectors/likwid/groups/power9/L2LOAD.txt new file mode 100644 index 0000000..ebac5a2 --- /dev/null +++ b/collectors/likwid/groups/power9/L2LOAD.txt @@ -0,0 +1,23 @@ +SHORT L2 cache bandwidth in MBytes/s + +EVENTSET +PMC0 PM_L2_LD +PMC2 PM_L2_INST +PMC4 PM_RUN_INST_CMPL +PMC5 PM_RUN_CYC + + +METRICS +Runtime (RDTSC) [s] time +CPI PMC5/PMC4 +L2 load bandwidth [MBytes/s] 1.0E-06*(PMC0+PMC2)*128.0/time +L2 load data volume [GBytes] 1.0E-09*(PMC0+PMC2)*128.0 + +LONG +Formulas: +CPI = PM_RUN_CYC/PM_RUN_INST_CMPL +L2 load bandwidth [MBytes/s] = 1.0E-06*(PM_L2_LD+PM_L2_INST)*128.0/time +L2 load data volume [GBytes] = 1.0E-09*(PM_L2_LD+PM_L2_INST)*128.0 +- +Profiling group to measure L2 load cache bandwidth. The bandwidth is computed by the +number of cacheline loaded from L2 cache to L1. diff --git a/collectors/likwid/groups/power9/L2STORE.txt b/collectors/likwid/groups/power9/L2STORE.txt new file mode 100644 index 0000000..3b1c0af --- /dev/null +++ b/collectors/likwid/groups/power9/L2STORE.txt @@ -0,0 +1,22 @@ +SHORT L2 cache bandwidth in MBytes/s + +EVENTSET +PMC0 PM_L2_ST +PMC4 PM_RUN_INST_CMPL +PMC5 PM_RUN_CYC + + +METRICS +Runtime (RDTSC) [s] time +CPI PMC5/PMC4 +L2 store bandwidth [MBytes/s] 1.0E-06*(PMC0)*128.0/time +L2 store data volume [GBytes] 1.0E-09*(PMC0)*128.0 + +LONG +Formulas: +CPI = PM_RUN_CYC/PM_RUN_INST_CMPL +L2 load bandwidth [MBytes/s] = 1.0E-06*(PM_L2_ST)*128.0/time +L2 load data volume [GBytes] = 1.0E-09*(PM_L2_ST)*128.0 +- +Profiling group to measure L2 store cache bandwidth. The bandwidth is computed by the +number of cacheline stored from L1 cache to L2. diff --git a/collectors/likwid/groups/power9/L3.txt b/collectors/likwid/groups/power9/L3.txt new file mode 100644 index 0000000..cb97ead --- /dev/null +++ b/collectors/likwid/groups/power9/L3.txt @@ -0,0 +1,29 @@ +SHORT L3 cache bandwidth in MBytes/s + +EVENTSET +PMC0 PM_L3_LD_PREF +PMC3 PM_DATA_FROM_L3 +PMC4 PM_RUN_INST_CMPL +PMC5 PM_RUN_CYC + + +METRICS +Runtime (RDTSC) [s] time +CPI PMC5/PMC4 +L3D load bandwidth [MBytes/s] 1.0E-06*(PMC3+PMC0)*128.0/time +L3D load data volume [GBytes] 1.0E-09*(PMC3+PMC0)*128.0 +Loads from local L3 per cycle 100.0*(PMC3+PMC0)/PMC5 + +LONG +Formulas: +CPI = PM_RUN_CYC/PM_RUN_INST_CMPL +L3D load bandwidth [MBytes/s] = 1.0E-06*(PM_DATA_FROM_L3)*128.0/time +L3D load data volume [GBytes] = 1.0E-09*(PM_DATA_FROM_L3)*128.0 +L3D evict bandwidth [MBytes/s] = 1.0E-06*(PM_L2_CASTOUT_MOD)*128.0/time +L3D evict data volume [GBytes] = 1.0E-09*(PM_L2_CASTOUT_MOD)*128.0 +L3 bandwidth [MBytes/s] = 1.0E-06*(PM_DATA_FROM_L3+PM_L2_CASTOUT_MOD)*128.0/time +L3 data volume [GBytes] = 1.0E-09*(PM_DATA_FROM_L3+PM_L2_CASTOUT_MOD)*128.0 +- +Profiling group to measure L3 cache bandwidth. The bandwidth is computed by the +number of cacheline loaded from the L3 to the L2 data cache. There is currently no +event to get the evicted data volume. diff --git a/collectors/likwid/groups/power9/MEM.txt b/collectors/likwid/groups/power9/MEM.txt new file mode 100644 index 0000000..022d39d --- /dev/null +++ b/collectors/likwid/groups/power9/MEM.txt @@ -0,0 +1,47 @@ +SHORT Main memory bandwidth in MBytes/s + +EVENTSET +PMC4 PM_RUN_INST_CMPL +PMC5 PM_RUN_CYC +MBOX0C0 PM_MBA0_READ_BYTES +MBOX0C1 PM_MBA0_WRITE_BYTES +MBOX1C0 PM_MBA1_READ_BYTES +MBOX1C1 PM_MBA1_WRITE_BYTES +MBOX2C0 PM_MBA2_READ_BYTES +MBOX2C1 PM_MBA2_WRITE_BYTES +MBOX3C0 PM_MBA3_READ_BYTES +MBOX3C1 PM_MBA3_WRITE_BYTES +MBOX4C0 PM_MBA4_READ_BYTES +MBOX4C1 PM_MBA4_WRITE_BYTES +MBOX5C0 PM_MBA5_READ_BYTES +MBOX5C1 PM_MBA5_WRITE_BYTES +MBOX6C0 PM_MBA6_READ_BYTES +MBOX6C1 PM_MBA6_WRITE_BYTES +MBOX7C0 PM_MBA7_READ_BYTES +MBOX7C1 PM_MBA7_WRITE_BYTES + + + +METRICS +Runtime (RDTSC) [s] time +CPI PMC5/PMC4 +Memory read bandwidth [MBytes/s] 1.0E-06*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX6C0+MBOX7C0)*64.0/time +Memory read data volume [GBytes] 1.0E-09*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX6C0+MBOX7C0)*64.0 +Memory write bandwidth [MBytes/s] 1.0E-06*(MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1+MBOX6C1+MBOX7C1)*64.0/time +Memory write data volume [GBytes] 1.0E-09*(MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1+MBOX6C1+MBOX7C1)*64.0 +Memory bandwidth [MBytes/s] 1.0E-06*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX6C0+MBOX7C0+MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1+MBOX6C1+MBOX7C1)*64.0/time +Memory data volume [GBytes] 1.0E-09*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX6C0+MBOX7C0+MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1+MBOX6C1+MBOX7C1)*64.0 + +LONG +Formulas: +Memory read bandwidth [MBytes/s] = 1.0E-06*(SUM(PM_MBAx_READ_BYTES))*64.0/runtime +Memory read data volume [GBytes] = 1.0E-09*(SUM(PM_MBAx_READ_BYTES))*64.0 +Memory write bandwidth [MBytes/s] = 1.0E-06*(SUM(PM_MBAx_WRITE_BYTES))*64.0/runtime +Memory write data volume [GBytes] = 1.0E-09*(SUM(PM_MBAx_WRITE_BYTES))*64.0 +Memory bandwidth [MBytes/s] = 1.0E-06*(SUM(PM_MBAx_READ_BYTES)+SUM(PM_MBAx_WRITE_BYTES))*64.0/runtime +Memory data volume [GBytes] = 1.0E-09*(SUM(PM_MBAx_READ_BYTES)+SUM(PM_MBAx_WRITE_BYTES))*64.0 +- +Profiling group to measure memory bandwidth drawn by all cores of a socket. +Since this group is based on Uncore events it is only possible to measure on a +per socket base. Some of the counters may not be available on your system. +Also outputs total data volume transferred from main memory. diff --git a/collectors/likwid/groups/power9/TLB_DATA.txt b/collectors/likwid/groups/power9/TLB_DATA.txt new file mode 100644 index 0000000..3d77654 --- /dev/null +++ b/collectors/likwid/groups/power9/TLB_DATA.txt @@ -0,0 +1,42 @@ +SHORT L1 Data TLB miss rate/ratio + +EVENTSET +PMC0 PM_LSU_DTLB_MISS_16G_1G +PMC1 PM_LSU_DTLB_MISS_4K +PMC2 PM_LSU_DTLB_MISS_64K +PMC3 PM_LSU_DTLB_MISS_16M_2M +PMC4 PM_RUN_INST_CMPL +PMC5 PM_RUN_CYC + +METRICS +Runtime (RDTSC) [s] time +CPI PMC5/PMC4 +L1 DTLB 4K misses PMC1 +L1 DTLB 4K miss rate PMC1/PMC4 +L1 DTLB 4K miss ratio [%] (PMC1/(PMC0+PMC1+PMC2+PMC3))*100.0 +L1 DTLB 64K misses PMC2 +L1 DTLB 64K miss rate PMC2/PMC4 +L1 DTLB 64K miss ratio [%] (PMC2/(PMC0+PMC1+PMC2+PMC3))*100.0 +L1 DTLB 16M/2M misses PMC3 +L1 DTLB 16M/2M miss rate PMC3/PMC4 +L1 DTLB 16M/2M miss ratio [%] (PMC3/(PMC0+PMC1+PMC2+PMC3))*100.0 +L1 DTLB 16G/1G misses PMC0 +L1 DTLB 16G/1G miss rate PMC0/PMC4 +L1 DTLB 16G/1G miss ratio [%] (PMC0/(PMC0+PMC1+PMC2+PMC3))*100.0 + +LONG +Formulas: +L1 DTLB 4K misses = PM_LSU_DTLB_MISS_4K +L1 DTLB 4K miss rate = PM_LSU_DTLB_MISS_4K/PM_RUN_INST_CMPL +L1 DTLB 4K miss ratio [%] = (PM_LSU_DTLB_MISS_4K/(PM_LSU_DTLB_MISS_4K+PM_DTLB_MISS_64K+PM_DTLB_MISS_16M_2M+PM_DTLB_MISS_16G_1G))*100 +L1 DTLB 64K misses = PM_LSU_DTLB_MISS_64K +L1 DTLB 64K miss rate = PM_LSU_DTLB_MISS_64K/PM_RUN_INST_CMPL +L1 DTLB 64K miss ratio [%] = (PM_LSU_DTLB_MISS_64K/(PM_LSU_DTLB_MISS_4K+PM_DTLB_MISS_64K+PM_DTLB_MISS_16M_2M+PM_DTLB_MISS_16G_1G))*100 +L1 DTLB 4K misses = PM_LSU_DTLB_MISS_4K +L1 DTLB 4K miss rate = PM_LSU_DTLB_MISS_4K/PM_RUN_INST_CMPL +L1 DTLB 4K miss ratio [%] = (PM_LSU_DTLB_MISS_4K/(PM_LSU_DTLB_MISS_4K+PM_DTLB_MISS_64K+PM_DTLB_MISS_16M_2M+PM_DTLB_MISS_16G_1G))*100 +L1 DTLB 4K misses = PM_LSU_DTLB_MISS_4K +L1 DTLB 4K miss rate = PM_LSU_DTLB_MISS_4K/PM_RUN_INST_CMPL +L1 DTLB 4K miss ratio [%] = (PM_LSU_DTLB_MISS_4K/(PM_LSU_DTLB_MISS_4K+PM_DTLB_MISS_64K+PM_DTLB_MISS_16M_2M+PM_DTLB_MISS_16G_1G))*100 +- +This group measures the data TLB misses for different page sizes. diff --git a/collectors/likwid/groups/power9/TLB_INSTR.txt b/collectors/likwid/groups/power9/TLB_INSTR.txt new file mode 100644 index 0000000..dc99d8a --- /dev/null +++ b/collectors/likwid/groups/power9/TLB_INSTR.txt @@ -0,0 +1,21 @@ +SHORT L1 Instruction TLB miss rate/ratio + +EVENTSET +PMC3 PM_ITLB_MISS +PMC4 PM_RUN_INST_CMPL +PMC5 PM_RUN_CYC + +METRICS +Runtime (RDTSC) [s] time +CPI PMC5/PMC4 +L1 ITLB misses PMC3 +L1 ITLB miss rate PMC3/PMC4 + +LONG +Formulas: +L1 ITLB misses = PM_ITLB_MISS +L1 ITLB miss rate = PM_ITLB_MISS/PM_RUN_INST_CMPL +- +This group measures the reloads of the instruction TLB. +Misses to the HPT are counted once while misses in the Radix +tree count the number of tree levels traversed. diff --git a/collectors/likwid/groups/power9/USEFUL.txt b/collectors/likwid/groups/power9/USEFUL.txt new file mode 100644 index 0000000..bbc20a0 --- /dev/null +++ b/collectors/likwid/groups/power9/USEFUL.txt @@ -0,0 +1,22 @@ +SHORT Rate of useful instructions + +EVENTSET +PMC0 PM_RUN_SPURR +PMC1 PM_INST_DISP +PMC3 PM_RUN_PURR +PMC4 PM_RUN_INST_CMPL +PMC5 PM_RUN_CYC + +METRICS +CPI PMC5/PMC4 +Useful instr. rate [%] (PMC4/PMC1)*100.0 +Processor Utilization [%] (PMC0/PMC3)*100.0 + + +LONG +Formulas: +Useful instr. rate [%] = (PM_RUN_INST_CMPL/PM_INST_DISP)*100 +Processor Utilization [%] = (PM_RUN_SPURR/PM_RUN_PURR)*100 +-- +This performance group shows the overhead of speculative +execution of instructions and the processor utilization. diff --git a/collectors/likwid/groups/sandybridge/BRANCH.txt b/collectors/likwid/groups/sandybridge/BRANCH.txt new file mode 100644 index 0000000..b8d41b2 --- /dev/null +++ b/collectors/likwid/groups/sandybridge/BRANCH.txt @@ -0,0 +1,31 @@ +SHORT Branch prediction miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 BR_INST_RETIRED_ALL_BRANCHES +PMC1 BR_MISP_RETIRED_ALL_BRANCHES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Branch rate PMC0/FIXC0 +Branch misprediction rate PMC1/FIXC0 +Branch misprediction ratio PMC1/PMC0 +Instructions per branch FIXC0/PMC0 + +LONG +Formulas: +Branch rate = BR_INST_RETIRED_ALL_BRANCHES/INSTR_RETIRED_ANY +Branch misprediction rate = BR_MISP_RETIRED_ALL_BRANCHES/INSTR_RETIRED_ANY +Branch misprediction ratio = BR_MISP_RETIRED_ALL_BRANCHES/BR_INST_RETIRED_ALL_BRANCHES +Instructions per branch = INSTR_RETIRED_ANY/BR_INST_RETIRED_ALL_BRANCHES +- +The rates state how often on average a branch or a mispredicted branch occurred +per instruction retired in total. The branch misprediction ratio sets directly +into relation what ratio of all branch instruction where mispredicted. +Instructions per branch is 1/branch rate. + diff --git a/collectors/likwid/groups/sandybridge/CLOCK.txt b/collectors/likwid/groups/sandybridge/CLOCK.txt new file mode 100644 index 0000000..a888d66 --- /dev/null +++ b/collectors/likwid/groups/sandybridge/CLOCK.txt @@ -0,0 +1,30 @@ +SHORT Power and Energy consumption + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PWR0 PWR_PKG_ENERGY +PWR3 PWR_DRAM_ENERGY +UBOXFIX UNCORE_CLOCK + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +Uncore Clock [MHz] 1.E-06*UBOXFIX/time +CPI FIXC1/FIXC0 +Energy [J] PWR0 +Power [W] PWR0/time +Energy DRAM [J] PWR3 +Power DRAM [W] PWR3/time + +LONG +Formulas: +Power = PWR_PKG_ENERGY / time +Power DRAM = PWR_DRAM_ENERGY / time +Uncore Clock [MHz] = 1.E-06 * UNCORE_CLOCK / time +- +SandyBridge implements the new RAPL interface. This interface enables to +monitor the consumed energy on the package (socket) and DRAM level. + diff --git a/collectors/likwid/groups/sandybridge/CYCLE_ACTIVITY.txt b/collectors/likwid/groups/sandybridge/CYCLE_ACTIVITY.txt new file mode 100644 index 0000000..8dbfe25 --- /dev/null +++ b/collectors/likwid/groups/sandybridge/CYCLE_ACTIVITY.txt @@ -0,0 +1,33 @@ +SHORT Cycle Activities + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 CYCLE_ACTIVITY_CYCLES_L2_PENDING +PMC2 CYCLE_ACTIVITY_CYCLES_L1D_PENDING +PMC3 CYCLE_ACTIVITY_CYCLES_NO_EXECUTE + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Cycles without execution [%] (PMC3/FIXC1)*100 +Cycles without execution due to L1D [%] (PMC2/FIXC1)*100 +Cycles without execution due to L2 [%] (PMC0/FIXC1)*100 + +LONG +Formulas: +Cycles without execution [%] = CYCLE_ACTIVITY_CYCLES_NO_EXECUTE/CPU_CLK_UNHALTED_CORE*100 +Cycles with stalls due to L1D [%] = CYCLE_ACTIVITY_CYCLES_L1D_PENDING/CPU_CLK_UNHALTED_CORE*100 +Cycles with stalls due to L2 [%] = CYCLE_ACTIVITY_CYCLES_L2_PENDING/CPU_CLK_UNHALTED_CORE*100 +-- +This performance group measures the cycles while waiting for data from the cache +and memory hierarchy. +CYCLE_ACTIVITY_CYCLES_NO_EXECUTE: Counts number of cycles nothing is executed on +any execution port. +CYCLE_ACTIVITY_CYCLES_L1D_PENDING: Cycles while L1 cache miss demand load is +outstanding. +CYCLE_ACTIVITY_CYCLES_L2_PENDING: Cycles while L2 cache miss demand load is +outstanding. diff --git a/collectors/likwid/groups/sandybridge/CYCLE_STALLS.txt b/collectors/likwid/groups/sandybridge/CYCLE_STALLS.txt new file mode 100644 index 0000000..d66cbb1 --- /dev/null +++ b/collectors/likwid/groups/sandybridge/CYCLE_STALLS.txt @@ -0,0 +1,38 @@ +SHORT Cycle Activities (Stalls) + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 CYCLE_ACTIVITY_STALLS_L2_PENDING +PMC2 CYCLE_ACTIVITY_STALLS_L1D_PENDING +PMC3 CYCLE_ACTIVITY_STALLS_TOTAL + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Total execution stalls PMC3 +Stalls caused by L1D misses [%] (PMC2/PMC3)*100 +Stalls caused by L2 misses [%] (PMC0/PMC3)*100 +Execution stall rate [%] (PMC3/FIXC1)*100 +Stalls caused by L1D misses rate [%] (PMC2/FIXC1)*100 +Stalls caused by L2 misses rate [%] (PMC0/FIXC1)*100 + +LONG +Formulas: +Total execution stalls = CYCLE_ACTIVITY_STALLS_TOTAL +Stalls caused by L1D misses [%] = (CYCLE_ACTIVITY_STALLS_L1D_PENDING/CYCLE_ACTIVITY_STALLS_TOTAL)*100 +Stalls caused by L2 misses [%] = (CYCLE_ACTIVITY_STALLS_L2_PENDING/CYCLE_ACTIVITY_STALLS_TOTAL)*100 +Execution stall rate [%] = (CYCLE_ACTIVITY_STALLS_TOTAL/CPU_CLK_UNHALTED_CORE)*100 +Stalls caused by L1D misses rate [%] = (CYCLE_ACTIVITY_STALLS_L1D_PENDING/CPU_CLK_UNHALTED_CORE)*100 +Stalls caused by L2 misses rate [%] = (CYCLE_ACTIVITY_STALLS_L2_PENDING/CPU_CLK_UNHALTED_CORE)*100 +-- +This performance group measures the stalls caused by data traffic in the cache +hierarchy. +CYCLE_ACTIVITY_STALLS_TOTAL: Total execution stalls. +CYCLE_ACTIVITY_STALLS_L1D_PENDING: Execution stalls while L1 cache miss demand +load is outstanding. +CYCLE_ACTIVITY_STALLS_L2_PENDING: Execution stalls while L2 cache miss demand +load is outstanding. diff --git a/collectors/likwid/groups/sandybridge/DATA.txt b/collectors/likwid/groups/sandybridge/DATA.txt new file mode 100644 index 0000000..967cbad --- /dev/null +++ b/collectors/likwid/groups/sandybridge/DATA.txt @@ -0,0 +1,22 @@ +SHORT Load to store ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 MEM_UOPS_RETIRED_LOADS +PMC1 MEM_UOPS_RETIRED_STORES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Load to store ratio PMC0/PMC1 + +LONG +Formulas: +Load to store ratio = MEM_UOPS_RETIRED_LOADS/MEM_UOPS_RETIRED_STORES +- +This is a metric to determine your load to store ratio. + diff --git a/collectors/likwid/groups/sandybridge/DIVIDE.txt b/collectors/likwid/groups/sandybridge/DIVIDE.txt new file mode 100644 index 0000000..504181c --- /dev/null +++ b/collectors/likwid/groups/sandybridge/DIVIDE.txt @@ -0,0 +1,24 @@ +SHORT Divide unit information + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 ARITH_NUM_DIV +PMC1 ARITH_FPU_DIV_ACTIVE + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Number of divide ops PMC0 +Avg. divide unit usage duration PMC1/PMC0 + +LONG +Formulas: +Number of divide ops = ARITH_NUM_DIV +Avg. divide unit usage duration = ARITH_FPU_DIV_ACTIVE/ARITH_NUM_DIV +- +This performance group measures the average latency of divide operations diff --git a/collectors/likwid/groups/sandybridge/ENERGY.txt b/collectors/likwid/groups/sandybridge/ENERGY.txt new file mode 100644 index 0000000..9898c70 --- /dev/null +++ b/collectors/likwid/groups/sandybridge/ENERGY.txt @@ -0,0 +1,37 @@ +SHORT Power and Energy consumption + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +TMP0 TEMP_CORE +PWR0 PWR_PKG_ENERGY +PWR1 PWR_PP0_ENERGY +PWR2 PWR_PP1_ENERGY +PWR3 PWR_DRAM_ENERGY + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Temperature [C] TMP0 +Energy [J] PWR0 +Power [W] PWR0/time +Energy PP0 [J] PWR1 +Power PP0 [W] PWR1/time +Energy PP1 [J] PWR2 +Power PP1 [W] PWR2/time +Energy DRAM [J] PWR3 +Power DRAM [W] PWR3/time + +LONG +Formulas: +Power = PWR_PKG_ENERGY / time +Power PP0 = PWR_PP0_ENERGY / time +Power PP1 = PWR_PP1_ENERGY / time +Power DRAM = PWR_DRAM_ENERGY / time +- +SandyBridge implements the new RAPL interface. This interface enables to +monitor the consumed energy on the package (socket) level. + diff --git a/collectors/likwid/groups/sandybridge/FALSE_SHARE.txt b/collectors/likwid/groups/sandybridge/FALSE_SHARE.txt new file mode 100644 index 0000000..fbec3f4 --- /dev/null +++ b/collectors/likwid/groups/sandybridge/FALSE_SHARE.txt @@ -0,0 +1,25 @@ +SHORT False sharing + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 MEM_LOAD_UOPS_LLC_HIT_RETIRED_XSNP_HITM +PMC2 MEM_LOAD_UOPS_RETIRED_ALL + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Local LLC false sharing [MByte] 1.E-06*PMC0*64 +Local LLC false sharing rate PMC0/PMC2 + +LONG +Formulas: +Local LLC false sharing [MByte] = 1.E-06*MEM_LOAD_UOPS_LLC_HIT_RETIRED_XSNP_HITM*64 +Local LLC false sharing rate = MEM_LOAD_UOPS_LLC_HIT_RETIRED_XSNP_HITM/MEM_LOAD_UOPS_RETIRED_ALL +- +False-sharing of cache lines can dramatically reduce the performance of an +application. This performance group measures the L3 traffic induced by false-sharing. +The false-sharing rate uses all memory loads as reference. diff --git a/collectors/likwid/groups/sandybridge/FLOPS_AVX.txt b/collectors/likwid/groups/sandybridge/FLOPS_AVX.txt new file mode 100644 index 0000000..5a3f14f --- /dev/null +++ b/collectors/likwid/groups/sandybridge/FLOPS_AVX.txt @@ -0,0 +1,26 @@ +SHORT Packed AVX MFLOP/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 SIMD_FP_256_PACKED_SINGLE +PMC1 SIMD_FP_256_PACKED_DOUBLE + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Packed SP [MFLOP/s] 1.0E-06*(PMC0*8.0)/time +Packed DP [MFLOP/s] 1.0E-06*(PMC1*4.0)/time + +LONG +Formulas: +Packed SP [MFLOP/s] = 1.0E-06*(SIMD_FP_256_PACKED_SINGLE*8)/runtime +Packed DP [MFLOP/s] = 1.0E-06*(SIMD_FP_256_PACKED_DOUBLE*4)/runtime +- +Packed 32b AVX FLOPs rates. +Please note that the current FLOP measurements on SandyBridge are +potentially wrong. So you cannot trust these counters at the moment! + diff --git a/collectors/likwid/groups/sandybridge/FLOPS_DP.txt b/collectors/likwid/groups/sandybridge/FLOPS_DP.txt new file mode 100644 index 0000000..91f8a86 --- /dev/null +++ b/collectors/likwid/groups/sandybridge/FLOPS_DP.txt @@ -0,0 +1,33 @@ +SHORT Double Precision MFLOP/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 FP_COMP_OPS_EXE_SSE_FP_PACKED_DOUBLE +PMC1 FP_COMP_OPS_EXE_SSE_FP_SCALAR_DOUBLE +PMC2 SIMD_FP_256_PACKED_DOUBLE + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +DP [MFLOP/s] 1.0E-06*(PMC0*2.0+PMC1+PMC2*4.0)/time +AVX DP [MFLOP/s] 1.0E-06*(PMC2*4.0)/time +Packed [MUOPS/s] 1.0E-06*(PMC0+PMC2)/time +Scalar [MUOPS/s] 1.0E-06*PMC1/time +Vectorization ratio 100*(PMC0+PMC2)/(PMC0+PMC1+PMC2) + +LONG +Formulas: +DP [MFLOP/s] = 1.0E-06*(FP_COMP_OPS_EXE_SSE_FP_PACKED*2+FP_COMP_OPS_EXE_SSE_FP_SCALAR+SIMD_FP_256_PACKED_DOUBLE*4)/runtime +AVX DP [MFLOP/s] = 1.0E-06*(SIMD_FP_256_PACKED_DOUBLE*4)/runtime +Packed [MUOPS/s] = 1.0E-06*(FP_COMP_OPS_EXE_SSE_FP_PACKED_DOUBLE+SIMD_FP_256_PACKED_DOUBLE)/runtime +Scalar [MUOPS/s] = 1.0E-06*FP_COMP_OPS_EXE_SSE_FP_SCALAR_DOUBLE/runtime +Vectorization ratio = 100*(FP_COMP_OPS_EXE_SSE_FP_PACKED_DOUBLE+SIMD_FP_256_PACKED_DOUBLE)/(FP_COMP_OPS_EXE_SSE_FP_SCALAR_DOUBLE+FP_COMP_OPS_EXE_SSE_FP_PACKED_DOUBLE+SIMD_FP_256_PACKED_DOUBLE) +- +SSE scalar and packed double precision FLOP rates. +Please note that the current FLOP measurements on SandyBridge are potentially +wrong. So you cannot trust these counters at the moment! + diff --git a/collectors/likwid/groups/sandybridge/FLOPS_SP.txt b/collectors/likwid/groups/sandybridge/FLOPS_SP.txt new file mode 100644 index 0000000..930a988 --- /dev/null +++ b/collectors/likwid/groups/sandybridge/FLOPS_SP.txt @@ -0,0 +1,33 @@ +SHORT Single Precision MFLOP/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 FP_COMP_OPS_EXE_SSE_FP_PACKED_SINGLE +PMC1 FP_COMP_OPS_EXE_SSE_FP_SCALAR_SINGLE +PMC2 SIMD_FP_256_PACKED_SINGLE + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +SP [MFLOP/s] 1.0E-06*(PMC0*4.0+PMC1+PMC2*8.0)/time +AVX SP [MFLOP/s] 1.0E-06*(PMC2*8.0)/time +Packed [MUOPS/s] 1.0E-06*(PMC0+PMC2)/time +Scalar [MUOPS/s] 1.0E-06*PMC1/time +Vectorization ratio 100*(PMC0+PMC2)/(PMC0+PMC1+PMC2) + +LONG +Formulas: +SP [MFLOP/s] = 1.0E-06*(FP_COMP_OPS_EXE_SSE_FP_PACKED*4+FP_COMP_OPS_EXE_SSE_FP_SCALAR+SIMD_FP_256_PACKED_SINGLE*8)/runtime +AVX SP [MFLOP/s] = 1.0E-06*(SIMD_FP_256_PACKED_SINGLE*8)/runtime +Packed [MUOPS/s] = 1.0E-06*(FP_COMP_OPS_EXE_SSE_FP_PACKED_SINGLE+SIMD_FP_256_PACKED_SINGLE)/runtime +Scalar [MUOPS/s] = 1.0E-06*FP_COMP_OPS_EXE_SSE_FP_SCALAR_SINGLE/runtime +Vectorization ratio = 100*(FP_COMP_OPS_EXE_SSE_FP_PACKED_SINGLE+SIMD_FP_256_PACKED_SINGLE)/(FP_COMP_OPS_EXE_SSE_FP_SCALAR_SINGLE+FP_COMP_OPS_EXE_SSE_FP_PACKED_SINGLE+SIMD_FP_256_PACKED_SINGLE) +- +SSE scalar and packed single precision FLOP rates. +Please note that the current FLOP measurements on SandyBridge are potentially +wrong. So you cannot trust these counters at the moment! + diff --git a/collectors/likwid/groups/sandybridge/ICACHE.txt b/collectors/likwid/groups/sandybridge/ICACHE.txt new file mode 100644 index 0000000..f1e2335 --- /dev/null +++ b/collectors/likwid/groups/sandybridge/ICACHE.txt @@ -0,0 +1,33 @@ +SHORT Instruction cache miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 ICACHE_ACCESSES +PMC1 ICACHE_MISSES +PMC2 ICACHE_IFETCH_STALL +PMC3 ILD_STALL_IQ_FULL + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L1I request rate PMC0/FIXC0 +L1I miss rate PMC1/FIXC0 +L1I miss ratio PMC1/PMC0 +L1I stalls PMC2 +L1I stall rate PMC2/FIXC0 +L1I queue full stalls PMC3 +L1I queue full stall rate PMC3/FIXC0 + +LONG +Formulas: +L1I request rate = ICACHE_ACCESSES / INSTR_RETIRED_ANY +L1I miss rate = ICACHE_MISSES / INSTR_RETIRED_ANY +L1I miss ratio = ICACHE_MISSES / ICACHE_ACCESSES +L1I stalls = ICACHE_IFETCH_STALL +L1I stall rate = ICACHE_IFETCH_STALL / INSTR_RETIRED_ANY +- +This group measures some L1 instruction cache metrics. diff --git a/collectors/likwid/groups/sandybridge/L2.txt b/collectors/likwid/groups/sandybridge/L2.txt new file mode 100644 index 0000000..1feb44c --- /dev/null +++ b/collectors/likwid/groups/sandybridge/L2.txt @@ -0,0 +1,38 @@ +SHORT L2 cache bandwidth in MBytes/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 L1D_REPLACEMENT +PMC1 L1D_M_EVICT +PMC2 ICACHE_MISSES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L2D load bandwidth [MBytes/s] 1.0E-06*PMC0*64.0/time +L2D load data volume [GBytes] 1.0E-09*PMC0*64.0 +L2D evict bandwidth [MBytes/s] 1.0E-06*PMC1*64.0/time +L2D evict data volume [GBytes] 1.0E-09*PMC1*64.0 +L2 bandwidth [MBytes/s] 1.0E-06*(PMC0+PMC1+PMC2)*64.0/time +L2 data volume [GBytes] 1.0E-09*(PMC0+PMC1+PMC2)*64.0 + +LONG +Formulas: +L2D load bandwidth [MBytes/s] = 1.0E-06*L1D_REPLACEMENT*64.0/time +L2D load data volume [GBytes] = 1.0E-09*L1D_REPLACEMENT*64.0 +L2D evict bandwidth [MBytes/s] = 1.0E-06*L1D_M_EVICT*64.0/time +L2D evict data volume [GBytes] = 1.0E-09*L1D_M_EVICT*64.0 +L2 bandwidth [MBytes/s] = 1.0E-06*(L1D_REPLACEMENT+L1D_M_EVICT+ICACHE_MISSES)*64/time +L2 data volume [GBytes] = 1.0E-09*(L1D_REPLACEMENT+L1D_M_EVICT+ICACHE_MISSES)*64 +- +Profiling group to measure L2 cache bandwidth. The bandwidth is computed by the +number of cache line allocated in the L1 and the number of modified cache lines +evicted from the L1. The group also output total data volume transferred between +L2 and L1. Note that this bandwidth also includes data transfers due to a write +allocate load on a store miss in L1 and traffic caused by misses in the +L1 instruction cache. + diff --git a/collectors/likwid/groups/sandybridge/L2CACHE.txt b/collectors/likwid/groups/sandybridge/L2CACHE.txt new file mode 100644 index 0000000..fbc3745 --- /dev/null +++ b/collectors/likwid/groups/sandybridge/L2CACHE.txt @@ -0,0 +1,34 @@ +SHORT L2 cache miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 L2_TRANS_ALL_REQUESTS +PMC1 L2_RQSTS_MISS + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L2 request rate PMC0/FIXC0 +L2 miss rate PMC1/FIXC0 +L2 miss ratio PMC1/PMC0 + +LONG +Formulas: +L2 request rate = L2_TRANS_ALL_REQUESTS/INSTR_RETIRED_ANY +L2 miss rate = L2_RQSTS_MISS/INSTR_RETIRED_ANY +L2 miss ratio = L2_RQSTS_MISS/L2_TRANS_ALL_REQUESTS +- +This group measures the locality of your data accesses with regard to the +L2 cache. L2 request rate tells you how data intensive your code is +or how many data accesses you have on average per instruction. +The L2 miss rate gives a measure how often it was necessary to get +cache lines from memory. And finally L2 miss ratio tells you how many of your +memory references required a cache line to be loaded from a higher level. +While the data cache miss rate might be given by your algorithm you should +try to get data cache miss ratio as low as possible by increasing your cache reuse. + + diff --git a/collectors/likwid/groups/sandybridge/L3.txt b/collectors/likwid/groups/sandybridge/L3.txt new file mode 100644 index 0000000..f63a918 --- /dev/null +++ b/collectors/likwid/groups/sandybridge/L3.txt @@ -0,0 +1,36 @@ +SHORT L3 cache bandwidth in MBytes/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 L2_LINES_IN_ALL +PMC1 L2_TRANS_L2_WB + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L3 load bandwidth [MBytes/s] 1.0E-06*PMC0*64.0/time +L3 load data volume [GBytes] 1.0E-09*PMC0*64.0 +L3 evict bandwidth [MBytes/s] 1.0E-06*PMC1*64.0/time +L3 evict data volume [GBytes] 1.0E-09*PMC1*64.0 +L3 bandwidth [MBytes/s] 1.0E-06*(PMC0+PMC1)*64.0/time +L3 data volume [GBytes] 1.0E-09*(PMC0+PMC1)*64.0 + +LONG +Formulas: +L3 load bandwidth [MBytes/s] = 1.0E-06*L2_LINES_IN_ALL*64.0/time +L3 load data volume [GBytes] = 1.0E-09*L2_LINES_IN_ALL*64.0 +L3 evict bandwidth [MBytes/s] = 1.0E-06*L2_TRANS_L2_WB*64.0/time +L3 evict data volume [GBytes] = 1.0E-09*L2_TRANS_L2_WB*64.0 +L3 bandwidth [MBytes/s] = 1.0E-06*(L2_LINES_IN_ALL+L2_TRANS_L2_WB)*64/time +L3 data volume [GBytes] = 1.0E-09*(L2_LINES_IN_ALL+L2_TRANS_L2_WB)*64 +- +Profiling group to measure L3 cache bandwidth. The bandwidth is computed by the +number of cache line allocated in the L2 and the number of modified cache lines +evicted from the L2. This group also output data volume transferred between the +L3 and measured cores L2 caches. Note that this bandwidth also includes data +transfers due to a write allocate load on a store miss in L2. + diff --git a/collectors/likwid/groups/sandybridge/L3CACHE.txt b/collectors/likwid/groups/sandybridge/L3CACHE.txt new file mode 100644 index 0000000..3dbb6cc --- /dev/null +++ b/collectors/likwid/groups/sandybridge/L3CACHE.txt @@ -0,0 +1,36 @@ +SHORT L3 cache miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0:MATCH0=0x0081:MATCH1=0x3fffc0 OFFCORE_RESPONSE_0_OPTIONS +PMC1:MATCH0=0x0081:MATCH1=0x1 OFFCORE_RESPONSE_1_OPTIONS +PMC2 L1D_REPLACEMENT + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L3 request rate PMC1/FIXC0 +L3 miss rate PMC0/FIXC0 +L3 miss ratio PMC0/PMC1 + +LONG +Formulas: +L3 request rate = OFFCORE_RESPONSE_1_OPTIONS:MATCH0=0x0081:MATCH1=0x1/INSTR_RETIRED_ANY +L3 miss rate = OFFCORE_RESPONSE_0_OPTIONS:MATCH0=0x0081:MATCH1=0x3fffc0/INSTR_RETIRED_ANY +L3 miss ratio = OFFCORE_RESPONSE_0_OPTIONS:MATCH0=0x0081:MATCH1=0x3fffc0/OFFCORE_RESPONSE_1_OPTIONS:MATCH0=0x0081:MATCH1=0x1 +- +This group measures the locality of your data accesses with regard to the +L3 cache. L3 request rate tells you how data intensive your code is +or how many data accesses you have on average per instruction. +The L3 miss rate gives a measure how often it was necessary to get +cache lines from L3 compared to all loaded cache lines in L1. +And finally L3 miss ratio tells you how many of your +memory references required a cache line to be loaded from a higher level. +While the data cache miss rate might be given by your algorithm you should +try to get data cache miss ratio as low as possible by increasing your cache reuse. + + diff --git a/collectors/likwid/groups/sandybridge/PORT_USAGE.txt b/collectors/likwid/groups/sandybridge/PORT_USAGE.txt new file mode 100644 index 0000000..d509607 --- /dev/null +++ b/collectors/likwid/groups/sandybridge/PORT_USAGE.txt @@ -0,0 +1,40 @@ +SHORT Execution port utilization + +REQUIRE_NOHT + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 UOPS_DISPATCHED_PORT_PORT_0 +PMC1 UOPS_DISPATCHED_PORT_PORT_1 +PMC2 UOPS_DISPATCHED_PORT_PORT_2 +PMC3 UOPS_DISPATCHED_PORT_PORT_3 +PMC4 UOPS_DISPATCHED_PORT_PORT_4 +PMC5 UOPS_DISPATCHED_PORT_PORT_5 + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Port0 usage ratio PMC0/(PMC0+PMC1+PMC2+PMC3+PMC4+PMC5) +Port1 usage ratio PMC1/(PMC0+PMC1+PMC2+PMC3+PMC4+PMC5) +Port2 usage ratio PMC2/(PMC0+PMC1+PMC2+PMC3+PMC4+PMC5) +Port3 usage ratio PMC3/(PMC0+PMC1+PMC2+PMC3+PMC4+PMC5) +Port4 usage ratio PMC4/(PMC0+PMC1+PMC2+PMC3+PMC4+PMC5) +Port5 usage ratio PMC5/(PMC0+PMC1+PMC2+PMC3+PMC4+PMC5) + +LONG +Formulas: +Port0 usage ratio = UOPS_DISPATCHED_PORT_PORT_0/SUM(UOPS_DISPATCHED_PORT_PORT_*) +Port1 usage ratio = UOPS_DISPATCHED_PORT_PORT_1/SUM(UOPS_DISPATCHED_PORT_PORT_*) +Port2 usage ratio = UOPS_DISPATCHED_PORT_PORT_2/SUM(UOPS_DISPATCHED_PORT_PORT_*) +Port3 usage ratio = UOPS_DISPATCHED_PORT_PORT_3/SUM(UOPS_DISPATCHED_PORT_PORT_*) +Port4 usage ratio = UOPS_DISPATCHED_PORT_PORT_4/SUM(UOPS_DISPATCHED_PORT_PORT_*) +Port5 usage ratio = UOPS_DISPATCHED_PORT_PORT_5/SUM(UOPS_DISPATCHED_PORT_PORT_*) +- +This group measures the execution port utilization in a CPU core. The group can +only be measured when HyperThreading is disabled because only then each CPU core +can program eight counters. diff --git a/collectors/likwid/groups/sandybridge/RECOVERY.txt b/collectors/likwid/groups/sandybridge/RECOVERY.txt new file mode 100644 index 0000000..7928ee4 --- /dev/null +++ b/collectors/likwid/groups/sandybridge/RECOVERY.txt @@ -0,0 +1,22 @@ +SHORT Recovery duration + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 INT_MISC_RECOVERY_CYCLES +PMC1 INT_MISC_RECOVERY_COUNT + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Avg. recovery duration PMC0/PMC1 + +LONG +Formulas: +Avg. recovery duration = INT_MISC_RECOVERY_CYCLES/INT_MISC_RECOVERY_COUNT +- +This group measures the duration of recoveries after SSE exception, memory +disambiguation, etc... diff --git a/collectors/likwid/groups/sandybridge/TLB_DATA.txt b/collectors/likwid/groups/sandybridge/TLB_DATA.txt new file mode 100644 index 0000000..8d94e05 --- /dev/null +++ b/collectors/likwid/groups/sandybridge/TLB_DATA.txt @@ -0,0 +1,35 @@ +SHORT L2 data TLB miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 DTLB_LOAD_MISSES_CAUSES_A_WALK +PMC1 DTLB_STORE_MISSES_CAUSES_A_WALK +PMC2 DTLB_LOAD_MISSES_WALK_DURATION +PMC3 DTLB_STORE_MISSES_WALK_DURATION + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L1 DTLB load misses PMC0 +L1 DTLB load miss rate PMC0/FIXC0 +L1 DTLB load miss duration [Cyc] PMC2/PMC0 +L1 DTLB store misses PMC1 +L1 DTLB store miss rate PMC1/FIXC0 +L1 DTLB store miss duration [Cyc] PMC3/PMC1 + +LONG +Formulas: +L1 DTLB load misses = DTLB_LOAD_MISSES_CAUSES_A_WALK +L1 DTLB load miss rate = DTLB_LOAD_MISSES_CAUSES_A_WALK / INSTR_RETIRED_ANY +L1 DTLB load miss duration [Cyc] = DTLB_LOAD_MISSES_WALK_DURATION / DTLB_LOAD_MISSES_CAUSES_A_WALK +L1 DTLB store misses = DTLB_STORE_MISSES_CAUSES_A_WALK +L1 DTLB store miss rate = DTLB_STORE_MISSES_CAUSES_A_WALK / INSTR_RETIRED_ANY +L1 DTLB store miss duration [Cyc] = DTLB_STORE_MISSES_WALK_DURATION / DTLB_STORE_MISSES_CAUSES_A_WALK +- +The DTLB load and store miss rates gives a measure how often a TLB miss occurred +per instruction. The duration measures the time in cycles how long a walk did take. + diff --git a/collectors/likwid/groups/sandybridge/TLB_INSTR.txt b/collectors/likwid/groups/sandybridge/TLB_INSTR.txt new file mode 100644 index 0000000..235d977 --- /dev/null +++ b/collectors/likwid/groups/sandybridge/TLB_INSTR.txt @@ -0,0 +1,28 @@ +SHORT L1 Instruction TLB miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 ITLB_MISSES_CAUSES_A_WALK +PMC1 ITLB_MISSES_WALK_DURATION + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L1 ITLB misses PMC0 +L1 ITLB miss rate PMC0/FIXC0 +L1 ITLB miss duration [Cyc] PMC1/PMC0 + + +LONG +Formulas: +L1 ITLB misses = ITLB_MISSES_CAUSES_A_WALK +L1 ITLB miss rate = ITLB_MISSES_CAUSES_A_WALK / INSTR_RETIRED_ANY +L1 ITLB miss duration [Cyc] = ITLB_MISSES_WALK_DURATION / ITLB_MISSES_CAUSES_A_WALK +- +The ITLB miss rates gives a measure how often a TLB miss occurred +per instruction. The duration measures the time in cycles how long a walk did take. + diff --git a/collectors/likwid/groups/sandybridge/TMA.txt b/collectors/likwid/groups/sandybridge/TMA.txt new file mode 100644 index 0000000..afb4126 --- /dev/null +++ b/collectors/likwid/groups/sandybridge/TMA.txt @@ -0,0 +1,48 @@ +SHORT Top down cycle allocation + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 UOPS_ISSUED_ANY +PMC1 UOPS_RETIRED_RETIRE_SLOTS +PMC2 IDQ_UOPS_NOT_DELIVERED_CORE +PMC3 INT_MISC_RECOVERY_CYCLES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +IPC FIXC0/FIXC1 +Total Slots 4*FIXC1 +Slots Retired PMC1 +Fetch Bubbles PMC2 +Recovery Bubbles 4*PMC3 +Front End [%] PMC2/(4*FIXC1)*100 +Speculation [%] (PMC0-PMC1+(4*PMC3))/(4*FIXC1)*100 +Retiring [%] PMC1/(4*FIXC1)*100 +Back End [%] (1-((PMC2+PMC0+(4*PMC3))/(4*FIXC1)))*100 + +LONG +Formulas: +Total Slots = 4*CPU_CLK_UNHALTED_CORE +Slots Retired = UOPS_RETIRED_RETIRE_SLOTS +Fetch Bubbles = IDQ_UOPS_NOT_DELIVERED_CORE +Recovery Bubbles = 4*INT_MISC_RECOVERY_CYCLES +Front End [%] = IDQ_UOPS_NOT_DELIVERED_CORE/(4*CPU_CLK_UNHALTED_CORE)*100 +Speculation [%] = (UOPS_ISSUED_ANY-UOPS_RETIRED_RETIRE_SLOTS+(4*INT_MISC_RECOVERY_CYCLES))/(4*CPU_CLK_UNHALTED_CORE)*100 +Retiring [%] = UOPS_RETIRED_RETIRE_SLOTS/(4*CPU_CLK_UNHALTED_CORE)*100 +Back End [%] = (1-((IDQ_UOPS_NOT_DELIVERED_CORE+UOPS_ISSUED_ANY+(4*INT_MISC_RECOVERY_CYCLES))/(4*CPU_CLK_UNHALTED_CORE)))*100 +-- +This performance group measures cycles to determine percentage of time spent in +front end, back end, retiring and speculation. These metrics are published and +verified by Intel. Further information: +Webpage describing Top-Down Method and its usage in Intel vTune: +https://software.intel.com/en-us/vtune-amplifier-help-tuning-applications-using-a-top-down-microarchitecture-analysis-method +Paper by Yasin Ahmad: +https://sites.google.com/site/analysismethods/yasin-pubs/TopDown-Yasin-ISPASS14.pdf?attredirects=0 +Slides by Yasin Ahmad: +http://www.cs.technion.ac.il/~erangi/TMA_using_Linux_perf__Ahmad_Yasin.pdf +The performance group was originally published here: +http://perf.mvermeulen.com/2018/04/14/top-down-performance-counter-analysis-part-1-likwid/ diff --git a/collectors/likwid/groups/sandybridge/UOPS.txt b/collectors/likwid/groups/sandybridge/UOPS.txt new file mode 100644 index 0000000..a4d35d8 --- /dev/null +++ b/collectors/likwid/groups/sandybridge/UOPS.txt @@ -0,0 +1,32 @@ +SHORT UOPs execution info + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 UOPS_ISSUED_ANY +PMC1 UOPS_EXECUTED_THREAD +PMC2 UOPS_RETIRED_ALL + + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Issued UOPs PMC0 +Executed UOPs PMC1 +Retired UOPs PMC2 + +LONG +Formulas: +Issued UOPs = UOPS_ISSUED_ANY +Executed UOPs = UOPS_EXECUTED_THREAD +Retired UOPs = UOPS_RETIRED_ALL +- +This group returns information about the instruction pipeline. It measures the +issued, executed and retired uOPs and returns the number of uOPs which were issued +but not executed as well as the number of uOPs which were executed but never retired. +The executed but not retired uOPs commonly come from speculatively executed branches. + diff --git a/collectors/likwid/groups/sandybridge/UOPS_EXEC.txt b/collectors/likwid/groups/sandybridge/UOPS_EXEC.txt new file mode 100644 index 0000000..7042df7 --- /dev/null +++ b/collectors/likwid/groups/sandybridge/UOPS_EXEC.txt @@ -0,0 +1,31 @@ +SHORT UOPs execution + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 UOPS_EXECUTED_USED_CYCLES +PMC1 UOPS_EXECUTED_STALL_CYCLES +PMC2 CPU_CLOCK_UNHALTED_TOTAL_CYCLES +PMC3:EDGEDETECT UOPS_EXECUTED_STALL_CYCLES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Used cycles ratio [%] 100*PMC0/PMC2 +Unused cycles ratio [%] 100*PMC1/PMC2 +Avg stall duration [cycles] PMC1/PMC3:EDGEDETECT + + +LONG +Formulas: +Used cycles ratio [%] = 100*UOPS_EXECUTED_USED_CYCLES/CPU_CLK_UNHALTED_CORE +Unused cycles ratio [%] = 100*UOPS_EXECUTED_STALL_CYCLES/CPU_CLK_UNHALTED_CORE +Avg stall duration [cycles] = UOPS_EXECUTED_STALL_CYCLES/UOPS_EXECUTED_STALL_CYCLES:EDGEDETECT +- +This performance group returns the ratios of used and unused cycles regarding +the execution stage in the pipeline. Used cycles are all cycles where uOPs are +executed while unused cycles refer to pipeline stalls. Moreover, the group +calculates the average stall duration in cycles. diff --git a/collectors/likwid/groups/sandybridge/UOPS_ISSUE.txt b/collectors/likwid/groups/sandybridge/UOPS_ISSUE.txt new file mode 100644 index 0000000..9aac923 --- /dev/null +++ b/collectors/likwid/groups/sandybridge/UOPS_ISSUE.txt @@ -0,0 +1,31 @@ +SHORT UOPs issueing + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 UOPS_ISSUED_USED_CYCLES +PMC1 UOPS_ISSUED_STALL_CYCLES +PMC2 CPU_CLOCK_UNHALTED_TOTAL_CYCLES +PMC3:EDGEDETECT UOPS_ISSUED_STALL_CYCLES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Used cycles ratio [%] 100*PMC0/PMC2 +Unused cycles ratio [%] 100*PMC1/PMC2 +Avg stall duration [cycles] PMC1/PMC3:EDGEDETECT + + +LONG +Formulas: +Used cycles ratio [%] = 100*UOPS_ISSUED_USED_CYCLES/CPU_CLK_UNHALTED_CORE +Unused cycles ratio [%] = 100*UOPS_ISSUED_STALL_CYCLES/CPU_CLK_UNHALTED_CORE +Avg stall duration [cycles] = UOPS_ISSUED_STALL_CYCLES/UOPS_ISSUED_STALL_CYCLES:EDGEDETECT +- +This performance group returns the ratios of used and unused cycles regarding +the issue stage in the pipeline. Used cycles are all cycles where uOPs are +issued while unused cycles refer to pipeline stalls. Moreover, the group +calculates the average stall duration in cycles. diff --git a/collectors/likwid/groups/sandybridge/UOPS_RETIRE.txt b/collectors/likwid/groups/sandybridge/UOPS_RETIRE.txt new file mode 100644 index 0000000..0f37585 --- /dev/null +++ b/collectors/likwid/groups/sandybridge/UOPS_RETIRE.txt @@ -0,0 +1,31 @@ +SHORT UOPs retirement + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 UOPS_RETIRED_USED_CYCLES +PMC1 UOPS_RETIRED_STALL_CYCLES +PMC2 CPU_CLOCK_UNHALTED_TOTAL_CYCLES +PMC3:EDGEDETECT UOPS_RETIRED_STALL_CYCLES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Used cycles ratio [%] 100*PMC0/PMC2 +Unused cycles ratio [%] 100*PMC1/PMC2 +Avg stall duration [cycles] PMC1/PMC3:EDGEDETECT + + +LONG +Formulas: +Used cycles ratio [%] = 100*UOPS_RETIRED_USED_CYCLES/CPU_CLK_UNHALTED_CORE +Unused cycles ratio [%] = 100*UOPS_RETIRED_STALL_CYCLES/CPU_CLK_UNHALTED_CORE +Avg stall duration [cycles] = UOPS_RETIRED_STALL_CYCLES/UOPS_RETIRED_STALL_CYCLES:EDGEDETECT +- +This performance group returns the ratios of used and unused cycles regarding +the retirement stage in the pipeline (re-order buffer). Used cycles are all +cycles where uOPs are retired while unused cycles refer to pipeline stalls. +Moreover, the group calculates the average stall duration in cycles. diff --git a/collectors/likwid/groups/sandybridgeEP/BRANCH.txt b/collectors/likwid/groups/sandybridgeEP/BRANCH.txt new file mode 100644 index 0000000..b8d41b2 --- /dev/null +++ b/collectors/likwid/groups/sandybridgeEP/BRANCH.txt @@ -0,0 +1,31 @@ +SHORT Branch prediction miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 BR_INST_RETIRED_ALL_BRANCHES +PMC1 BR_MISP_RETIRED_ALL_BRANCHES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Branch rate PMC0/FIXC0 +Branch misprediction rate PMC1/FIXC0 +Branch misprediction ratio PMC1/PMC0 +Instructions per branch FIXC0/PMC0 + +LONG +Formulas: +Branch rate = BR_INST_RETIRED_ALL_BRANCHES/INSTR_RETIRED_ANY +Branch misprediction rate = BR_MISP_RETIRED_ALL_BRANCHES/INSTR_RETIRED_ANY +Branch misprediction ratio = BR_MISP_RETIRED_ALL_BRANCHES/BR_INST_RETIRED_ALL_BRANCHES +Instructions per branch = INSTR_RETIRED_ANY/BR_INST_RETIRED_ALL_BRANCHES +- +The rates state how often on average a branch or a mispredicted branch occurred +per instruction retired in total. The branch misprediction ratio sets directly +into relation what ratio of all branch instruction where mispredicted. +Instructions per branch is 1/branch rate. + diff --git a/collectors/likwid/groups/sandybridgeEP/CACHES.txt b/collectors/likwid/groups/sandybridgeEP/CACHES.txt new file mode 100644 index 0000000..345b8f4 --- /dev/null +++ b/collectors/likwid/groups/sandybridgeEP/CACHES.txt @@ -0,0 +1,97 @@ +SHORT Some data from the CBOXes + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 L1D_REPLACEMENT +PMC1 L1D_M_EVICT +PMC2 L2_LINES_IN_ALL +PMC3 L2_TRANS_L2_WB +CBOX0C0:STATE=0x3F LLC_LOOKUP_DATA_READ +CBOX1C0:STATE=0x3F LLC_LOOKUP_DATA_READ +CBOX2C0:STATE=0x3F LLC_LOOKUP_DATA_READ +CBOX3C0:STATE=0x3F LLC_LOOKUP_DATA_READ +CBOX4C0:STATE=0x3F LLC_LOOKUP_DATA_READ +CBOX5C0:STATE=0x3F LLC_LOOKUP_DATA_READ +CBOX6C0:STATE=0x3F LLC_LOOKUP_DATA_READ +CBOX7C0:STATE=0x3F LLC_LOOKUP_DATA_READ +CBOX0C1 LLC_VICTIMS_M_STATE +CBOX1C1 LLC_VICTIMS_M_STATE +CBOX2C1 LLC_VICTIMS_M_STATE +CBOX3C1 LLC_VICTIMS_M_STATE +CBOX4C1 LLC_VICTIMS_M_STATE +CBOX5C1 LLC_VICTIMS_M_STATE +CBOX6C1 LLC_VICTIMS_M_STATE +CBOX7C1 LLC_VICTIMS_M_STATE +MBOX0C0 CAS_COUNT_RD +MBOX0C1 CAS_COUNT_WR +MBOX1C0 CAS_COUNT_RD +MBOX1C1 CAS_COUNT_WR +MBOX2C0 CAS_COUNT_RD +MBOX2C1 CAS_COUNT_WR +MBOX3C0 CAS_COUNT_RD +MBOX3C1 CAS_COUNT_WR + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L2 to L1 load bandwidth [MBytes/s] 1.0E-06*PMC0*64.0/time +L2 to L1 load data volume [GBytes] 1.0E-09*PMC0*64.0 +L1 to L2 evict bandwidth [MBytes/s] 1.0E-06*PMC1*64.0/time +L1 to L2 evict data volume [GBytes] 1.0E-09*PMC1*64.0 +L1 to/from L2 bandwidth [MBytes/s] 1.0E-06*(PMC0+PMC1)*64.0/time +L1 to/from L2 data volume [GBytes] 1.0E-09*(PMC0+PMC1)*64.0 +L3 to L2 load bandwidth [MBytes/s] 1.0E-06*PMC2*64.0/time +L3 to L2 load data volume [GBytes] 1.0E-09*PMC2*64.0 +L2 to L3 evict bandwidth [MBytes/s] 1.0E-06*PMC3*64.0/time +L2 to L3 evict data volume [GBytes] 1.0E-09*PMC3*64.0 +L2 to/from L3 bandwidth [MBytes/s] 1.0E-06*(PMC2+PMC3)*64.0/time +L2 to/from L3 data volume [GBytes] 1.0E-09*(PMC2+PMC3)*64.0 +System to L3 bandwidth [MBytes/s] 1.0E-06*(CBOX0C0:STATE=0x3F+CBOX1C0:STATE=0x3F+CBOX2C0:STATE=0x3F+CBOX3C0:STATE=0x3F+CBOX4C0:STATE=0x3F+CBOX5C0:STATE=0x3F+CBOX6C0:STATE=0x3F+CBOX7C0:STATE=0x3F)*64.0/time +System to L3 data volume [GBytes] 1.0E-09*(CBOX0C0:STATE=0x3F+CBOX1C0:STATE=0x3F+CBOX2C0:STATE=0x3F+CBOX3C0:STATE=0x3F+CBOX4C0:STATE=0x3F+CBOX5C0:STATE=0x3F+CBOX6C0:STATE=0x3F+CBOX7C0:STATE=0x3F)*64.0 +L3 to system bandwidth [MBytes/s] 1.0E-06*(CBOX0C1+CBOX1C1+CBOX2C1+CBOX3C1+CBOX4C1+CBOX5C1+CBOX6C1+CBOX7C1)*64.0/time +L3 to system data volume [GBytes] 1.0E-09*(CBOX0C1+CBOX1C1+CBOX2C1+CBOX3C1+CBOX4C1+CBOX5C1+CBOX6C1+CBOX7C1)*64.0 +L3 to/from system bandwidth [MBytes/s] 1.0E-06*(CBOX0C0:STATE=0x3F+CBOX1C0:STATE=0x3F+CBOX2C0:STATE=0x3F+CBOX3C0:STATE=0x3F+CBOX4C0:STATE=0x3F+CBOX5C0:STATE=0x3F+CBOX6C0:STATE=0x3F+CBOX7C0:STATE=0x3F+CBOX0C1+CBOX1C1+CBOX2C1+CBOX3C1+CBOX4C1+CBOX5C1+CBOX6C1+CBOX7C1)*64.0/time +L3 to/from system data volume [GBytes] 1.0E-09*(CBOX0C0:STATE=0x3F+CBOX1C0:STATE=0x3F+CBOX2C0:STATE=0x3F+CBOX3C0:STATE=0x3F+CBOX4C0:STATE=0x3F+CBOX5C0:STATE=0x3F+CBOX6C0:STATE=0x3F+CBOX7C0:STATE=0x3F+CBOX0C1+CBOX1C1+CBOX2C1+CBOX3C1+CBOX4C1+CBOX5C1+CBOX6C1+CBOX7C1)*64.0 +Memory read bandwidth [MBytes/s] 1.0E-06*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0)*64.0/time +Memory read data volume [GBytes] 1.0E-09*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0)*64.0 +Memory write bandwidth [MBytes/s] 1.0E-06*(MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1)*64.0/time +Memory write data volume [GBytes] 1.0E-09*(MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1)*64.0 +Memory bandwidth [MBytes/s] 1.0E-06*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1)*64.0/time +Memory data volume [GBytes] 1.0E-09*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1)*64.0 + + +LONG +Formulas: +L2 to L1 load bandwidth [MBytes/s] = 1.0E-06*L1D_REPLACEMENT*64/time +L2 to L1 load data volume [GBytes] = 1.0E-09*L1D_REPLACEMENT*64 +L1 to L2 evict bandwidth [MBytes/s] = 1.0E-06*L1D_M_EVICT*64/time +L1 to L2 evict data volume [GBytes] = 1.0E-09*L1D_M_EVICT*64 +L1 to/from L2 bandwidth [MBytes/s] = 1.0E-06*(L1D_REPLACEMENT+L1D_M_EVICT)*64/time +L1 to/from L2 data volume [GBytes] = 1.0E-09*(L1D_REPLACEMENT+L1D_M_EVICT)*64 +L3 to L2 load bandwidth [MBytes/s] = 1.0E-06*L2_LINES_IN_ALL*64/time +L3 to L2 load data volume [GBytes] = 1.0E-09*L2_LINES_IN_ALL*64 +L2 to L3 evict bandwidth [MBytes/s] = 1.0E-06*L2_TRANS_L2_WB*64/time +L2 to L3 evict data volume [GBytes] = 1.0E-09*L2_TRANS_L2_WB*64 +L2 to/from L3 bandwidth [MBytes/s] = 1.0E-06*(L2_LINES_IN_ALL+L2_TRANS_L2_WB)*64/time +L2 to/from L3 data volume [GBytes] = 1.0E-09*(L2_LINES_IN_ALL+L2_TRANS_L2_WB)*64 +System to L3 bandwidth [MBytes/s] = 1.0E-06*(SUM(LLC_LOOKUP_DATA_READ:STATE=0x3F))*64/time +System to L3 data volume [GBytes] = 1.0E-09*(SUM(LLC_LOOKUP_DATA_READ:STATE=0x3F))*64 +L3 to system bandwidth [MBytes/s] = 1.0E-06*(SUM(LLC_VICTIMS_M_STATE))*64/time +L3 to system data volume [GBytes] = 1.0E-09*(SUM(LLC_VICTIMS_M_STATE))*64 +L3 to/from system bandwidth [MBytes/s] = 1.0E-06*(SUM(LLC_LOOKUP_DATA_READ:STATE=0x3F)+SUM(LLC_VICTIMS_M_STATE))*64/time +L3 to/from system data volume [GBytes] = 1.0E-09*(SUM(LLC_LOOKUP_DATA_READ:STATE=0x3F)+SUM(LLC_VICTIMS_M_STATE))*64 +Memory read bandwidth [MBytes/s] = 1.0E-06*(SUM(CAS_COUNT_RD))*64.0/time +Memory read data volume [GBytes] = 1.0E-09*(SUM(CAS_COUNT_RD))*64.0 +Memory write bandwidth [MBytes/s] = 1.0E-06*(SUM(CAS_COUNT_WR))*64.0/time +Memory write data volume [GBytes] = 1.0E-09*(SUM(CAS_COUNT_WR))*64.0 +Memory bandwidth [MBytes/s] = 1.0E-06*(SUM(CAS_COUNT_RD)+SUM(CAS_COUNT_WR))*64.0/time +Memory data volume [GBytes] = 1.0E-09*(SUM(CAS_COUNT_RD)+SUM(CAS_COUNT_WR))*64.0 +- +Group to measure cache transfers between L1 and Memory. Please notice that the +L3 to/from system metrics contain any traffic to the system (memory, +Intel QPI, etc.) but don't seem to handle anything because commonly memory read +bandwidth and L3 to L2 bandwidth is higher as the memory to L3 bandwidth. diff --git a/collectors/likwid/groups/sandybridgeEP/CLOCK.txt b/collectors/likwid/groups/sandybridgeEP/CLOCK.txt new file mode 100644 index 0000000..a888d66 --- /dev/null +++ b/collectors/likwid/groups/sandybridgeEP/CLOCK.txt @@ -0,0 +1,30 @@ +SHORT Power and Energy consumption + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PWR0 PWR_PKG_ENERGY +PWR3 PWR_DRAM_ENERGY +UBOXFIX UNCORE_CLOCK + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +Uncore Clock [MHz] 1.E-06*UBOXFIX/time +CPI FIXC1/FIXC0 +Energy [J] PWR0 +Power [W] PWR0/time +Energy DRAM [J] PWR3 +Power DRAM [W] PWR3/time + +LONG +Formulas: +Power = PWR_PKG_ENERGY / time +Power DRAM = PWR_DRAM_ENERGY / time +Uncore Clock [MHz] = 1.E-06 * UNCORE_CLOCK / time +- +SandyBridge implements the new RAPL interface. This interface enables to +monitor the consumed energy on the package (socket) and DRAM level. + diff --git a/collectors/likwid/groups/sandybridgeEP/CYCLE_ACTIVITY.txt b/collectors/likwid/groups/sandybridgeEP/CYCLE_ACTIVITY.txt new file mode 100644 index 0000000..8dbfe25 --- /dev/null +++ b/collectors/likwid/groups/sandybridgeEP/CYCLE_ACTIVITY.txt @@ -0,0 +1,33 @@ +SHORT Cycle Activities + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 CYCLE_ACTIVITY_CYCLES_L2_PENDING +PMC2 CYCLE_ACTIVITY_CYCLES_L1D_PENDING +PMC3 CYCLE_ACTIVITY_CYCLES_NO_EXECUTE + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Cycles without execution [%] (PMC3/FIXC1)*100 +Cycles without execution due to L1D [%] (PMC2/FIXC1)*100 +Cycles without execution due to L2 [%] (PMC0/FIXC1)*100 + +LONG +Formulas: +Cycles without execution [%] = CYCLE_ACTIVITY_CYCLES_NO_EXECUTE/CPU_CLK_UNHALTED_CORE*100 +Cycles with stalls due to L1D [%] = CYCLE_ACTIVITY_CYCLES_L1D_PENDING/CPU_CLK_UNHALTED_CORE*100 +Cycles with stalls due to L2 [%] = CYCLE_ACTIVITY_CYCLES_L2_PENDING/CPU_CLK_UNHALTED_CORE*100 +-- +This performance group measures the cycles while waiting for data from the cache +and memory hierarchy. +CYCLE_ACTIVITY_CYCLES_NO_EXECUTE: Counts number of cycles nothing is executed on +any execution port. +CYCLE_ACTIVITY_CYCLES_L1D_PENDING: Cycles while L1 cache miss demand load is +outstanding. +CYCLE_ACTIVITY_CYCLES_L2_PENDING: Cycles while L2 cache miss demand load is +outstanding. diff --git a/collectors/likwid/groups/sandybridgeEP/CYCLE_STALLS.txt b/collectors/likwid/groups/sandybridgeEP/CYCLE_STALLS.txt new file mode 100644 index 0000000..d66cbb1 --- /dev/null +++ b/collectors/likwid/groups/sandybridgeEP/CYCLE_STALLS.txt @@ -0,0 +1,38 @@ +SHORT Cycle Activities (Stalls) + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 CYCLE_ACTIVITY_STALLS_L2_PENDING +PMC2 CYCLE_ACTIVITY_STALLS_L1D_PENDING +PMC3 CYCLE_ACTIVITY_STALLS_TOTAL + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Total execution stalls PMC3 +Stalls caused by L1D misses [%] (PMC2/PMC3)*100 +Stalls caused by L2 misses [%] (PMC0/PMC3)*100 +Execution stall rate [%] (PMC3/FIXC1)*100 +Stalls caused by L1D misses rate [%] (PMC2/FIXC1)*100 +Stalls caused by L2 misses rate [%] (PMC0/FIXC1)*100 + +LONG +Formulas: +Total execution stalls = CYCLE_ACTIVITY_STALLS_TOTAL +Stalls caused by L1D misses [%] = (CYCLE_ACTIVITY_STALLS_L1D_PENDING/CYCLE_ACTIVITY_STALLS_TOTAL)*100 +Stalls caused by L2 misses [%] = (CYCLE_ACTIVITY_STALLS_L2_PENDING/CYCLE_ACTIVITY_STALLS_TOTAL)*100 +Execution stall rate [%] = (CYCLE_ACTIVITY_STALLS_TOTAL/CPU_CLK_UNHALTED_CORE)*100 +Stalls caused by L1D misses rate [%] = (CYCLE_ACTIVITY_STALLS_L1D_PENDING/CPU_CLK_UNHALTED_CORE)*100 +Stalls caused by L2 misses rate [%] = (CYCLE_ACTIVITY_STALLS_L2_PENDING/CPU_CLK_UNHALTED_CORE)*100 +-- +This performance group measures the stalls caused by data traffic in the cache +hierarchy. +CYCLE_ACTIVITY_STALLS_TOTAL: Total execution stalls. +CYCLE_ACTIVITY_STALLS_L1D_PENDING: Execution stalls while L1 cache miss demand +load is outstanding. +CYCLE_ACTIVITY_STALLS_L2_PENDING: Execution stalls while L2 cache miss demand +load is outstanding. diff --git a/collectors/likwid/groups/sandybridgeEP/DATA.txt b/collectors/likwid/groups/sandybridgeEP/DATA.txt new file mode 100644 index 0000000..967cbad --- /dev/null +++ b/collectors/likwid/groups/sandybridgeEP/DATA.txt @@ -0,0 +1,22 @@ +SHORT Load to store ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 MEM_UOPS_RETIRED_LOADS +PMC1 MEM_UOPS_RETIRED_STORES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Load to store ratio PMC0/PMC1 + +LONG +Formulas: +Load to store ratio = MEM_UOPS_RETIRED_LOADS/MEM_UOPS_RETIRED_STORES +- +This is a metric to determine your load to store ratio. + diff --git a/collectors/likwid/groups/sandybridgeEP/DIVIDE.txt b/collectors/likwid/groups/sandybridgeEP/DIVIDE.txt new file mode 100644 index 0000000..504181c --- /dev/null +++ b/collectors/likwid/groups/sandybridgeEP/DIVIDE.txt @@ -0,0 +1,24 @@ +SHORT Divide unit information + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 ARITH_NUM_DIV +PMC1 ARITH_FPU_DIV_ACTIVE + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Number of divide ops PMC0 +Avg. divide unit usage duration PMC1/PMC0 + +LONG +Formulas: +Number of divide ops = ARITH_NUM_DIV +Avg. divide unit usage duration = ARITH_FPU_DIV_ACTIVE/ARITH_NUM_DIV +- +This performance group measures the average latency of divide operations diff --git a/collectors/likwid/groups/sandybridgeEP/ENERGY.txt b/collectors/likwid/groups/sandybridgeEP/ENERGY.txt new file mode 100644 index 0000000..1ab4ef3 --- /dev/null +++ b/collectors/likwid/groups/sandybridgeEP/ENERGY.txt @@ -0,0 +1,33 @@ +SHORT Power and Energy consumption + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +TMP0 TEMP_CORE +PWR0 PWR_PKG_ENERGY +PWR1 PWR_PP0_ENERGY +PWR3 PWR_DRAM_ENERGY + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Temperature [C] TMP0 +Energy [J] PWR0 +Power [W] PWR0/time +Energy PP0 [J] PWR1 +Power PP0 [W] PWR1/time +Energy DRAM [J] PWR3 +Power DRAM [W] PWR3/time + +LONG +Formulas: +Power = PWR_PKG_ENERGY / time +Power PP0 = PWR_PP0_ENERGY / time +Power DRAM = PWR_DRAM_ENERGY / time +- +SandyBridge implements the new RAPL interface. This interface enables to +monitor the consumed energy on the package (socket) level. + diff --git a/collectors/likwid/groups/sandybridgeEP/FALSE_SHARE.txt b/collectors/likwid/groups/sandybridgeEP/FALSE_SHARE.txt new file mode 100644 index 0000000..27f568a --- /dev/null +++ b/collectors/likwid/groups/sandybridgeEP/FALSE_SHARE.txt @@ -0,0 +1,27 @@ +SHORT False sharing + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 MEM_LOAD_UOPS_LLC_HIT_RETIRED_XSNP_HITM +PMC2 MEM_LOAD_UOPS_RETIRED_ALL + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Local LLC false sharing [MByte] 1.E-06*PMC0*64 +Local LLC false sharing rate PMC0/PMC2 + +LONG +Formulas: +Local LLC false sharing [MByte] = 1.E-06*MEM_LOAD_UOPS_LLC_HIT_RETIRED_XSNP_HITM*64 +Local LLC false sharing rate = MEM_LOAD_UOPS_LLC_HIT_RETIRED_XSNP_HITM/MEM_LOAD_UOPS_RETIRED_ALL +- +False-sharing of cache lines can dramatically reduce the performance of an +application. This performance group measures the L3 traffic induced by false-sharing. +The false-sharing rate uses all memory loads as reference. +Intel SandyBridge EP CPUs do not provide the events to measure the false-sharing +over CPU socket boundaries. diff --git a/collectors/likwid/groups/sandybridgeEP/FLOPS_AVX.txt b/collectors/likwid/groups/sandybridgeEP/FLOPS_AVX.txt new file mode 100644 index 0000000..5a3f14f --- /dev/null +++ b/collectors/likwid/groups/sandybridgeEP/FLOPS_AVX.txt @@ -0,0 +1,26 @@ +SHORT Packed AVX MFLOP/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 SIMD_FP_256_PACKED_SINGLE +PMC1 SIMD_FP_256_PACKED_DOUBLE + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Packed SP [MFLOP/s] 1.0E-06*(PMC0*8.0)/time +Packed DP [MFLOP/s] 1.0E-06*(PMC1*4.0)/time + +LONG +Formulas: +Packed SP [MFLOP/s] = 1.0E-06*(SIMD_FP_256_PACKED_SINGLE*8)/runtime +Packed DP [MFLOP/s] = 1.0E-06*(SIMD_FP_256_PACKED_DOUBLE*4)/runtime +- +Packed 32b AVX FLOPs rates. +Please note that the current FLOP measurements on SandyBridge are +potentially wrong. So you cannot trust these counters at the moment! + diff --git a/collectors/likwid/groups/sandybridgeEP/FLOPS_DP.txt b/collectors/likwid/groups/sandybridgeEP/FLOPS_DP.txt new file mode 100644 index 0000000..91f8a86 --- /dev/null +++ b/collectors/likwid/groups/sandybridgeEP/FLOPS_DP.txt @@ -0,0 +1,33 @@ +SHORT Double Precision MFLOP/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 FP_COMP_OPS_EXE_SSE_FP_PACKED_DOUBLE +PMC1 FP_COMP_OPS_EXE_SSE_FP_SCALAR_DOUBLE +PMC2 SIMD_FP_256_PACKED_DOUBLE + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +DP [MFLOP/s] 1.0E-06*(PMC0*2.0+PMC1+PMC2*4.0)/time +AVX DP [MFLOP/s] 1.0E-06*(PMC2*4.0)/time +Packed [MUOPS/s] 1.0E-06*(PMC0+PMC2)/time +Scalar [MUOPS/s] 1.0E-06*PMC1/time +Vectorization ratio 100*(PMC0+PMC2)/(PMC0+PMC1+PMC2) + +LONG +Formulas: +DP [MFLOP/s] = 1.0E-06*(FP_COMP_OPS_EXE_SSE_FP_PACKED*2+FP_COMP_OPS_EXE_SSE_FP_SCALAR+SIMD_FP_256_PACKED_DOUBLE*4)/runtime +AVX DP [MFLOP/s] = 1.0E-06*(SIMD_FP_256_PACKED_DOUBLE*4)/runtime +Packed [MUOPS/s] = 1.0E-06*(FP_COMP_OPS_EXE_SSE_FP_PACKED_DOUBLE+SIMD_FP_256_PACKED_DOUBLE)/runtime +Scalar [MUOPS/s] = 1.0E-06*FP_COMP_OPS_EXE_SSE_FP_SCALAR_DOUBLE/runtime +Vectorization ratio = 100*(FP_COMP_OPS_EXE_SSE_FP_PACKED_DOUBLE+SIMD_FP_256_PACKED_DOUBLE)/(FP_COMP_OPS_EXE_SSE_FP_SCALAR_DOUBLE+FP_COMP_OPS_EXE_SSE_FP_PACKED_DOUBLE+SIMD_FP_256_PACKED_DOUBLE) +- +SSE scalar and packed double precision FLOP rates. +Please note that the current FLOP measurements on SandyBridge are potentially +wrong. So you cannot trust these counters at the moment! + diff --git a/collectors/likwid/groups/sandybridgeEP/FLOPS_SP.txt b/collectors/likwid/groups/sandybridgeEP/FLOPS_SP.txt new file mode 100644 index 0000000..930a988 --- /dev/null +++ b/collectors/likwid/groups/sandybridgeEP/FLOPS_SP.txt @@ -0,0 +1,33 @@ +SHORT Single Precision MFLOP/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 FP_COMP_OPS_EXE_SSE_FP_PACKED_SINGLE +PMC1 FP_COMP_OPS_EXE_SSE_FP_SCALAR_SINGLE +PMC2 SIMD_FP_256_PACKED_SINGLE + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +SP [MFLOP/s] 1.0E-06*(PMC0*4.0+PMC1+PMC2*8.0)/time +AVX SP [MFLOP/s] 1.0E-06*(PMC2*8.0)/time +Packed [MUOPS/s] 1.0E-06*(PMC0+PMC2)/time +Scalar [MUOPS/s] 1.0E-06*PMC1/time +Vectorization ratio 100*(PMC0+PMC2)/(PMC0+PMC1+PMC2) + +LONG +Formulas: +SP [MFLOP/s] = 1.0E-06*(FP_COMP_OPS_EXE_SSE_FP_PACKED*4+FP_COMP_OPS_EXE_SSE_FP_SCALAR+SIMD_FP_256_PACKED_SINGLE*8)/runtime +AVX SP [MFLOP/s] = 1.0E-06*(SIMD_FP_256_PACKED_SINGLE*8)/runtime +Packed [MUOPS/s] = 1.0E-06*(FP_COMP_OPS_EXE_SSE_FP_PACKED_SINGLE+SIMD_FP_256_PACKED_SINGLE)/runtime +Scalar [MUOPS/s] = 1.0E-06*FP_COMP_OPS_EXE_SSE_FP_SCALAR_SINGLE/runtime +Vectorization ratio = 100*(FP_COMP_OPS_EXE_SSE_FP_PACKED_SINGLE+SIMD_FP_256_PACKED_SINGLE)/(FP_COMP_OPS_EXE_SSE_FP_SCALAR_SINGLE+FP_COMP_OPS_EXE_SSE_FP_PACKED_SINGLE+SIMD_FP_256_PACKED_SINGLE) +- +SSE scalar and packed single precision FLOP rates. +Please note that the current FLOP measurements on SandyBridge are potentially +wrong. So you cannot trust these counters at the moment! + diff --git a/collectors/likwid/groups/sandybridgeEP/ICACHE.txt b/collectors/likwid/groups/sandybridgeEP/ICACHE.txt new file mode 100644 index 0000000..f1e2335 --- /dev/null +++ b/collectors/likwid/groups/sandybridgeEP/ICACHE.txt @@ -0,0 +1,33 @@ +SHORT Instruction cache miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 ICACHE_ACCESSES +PMC1 ICACHE_MISSES +PMC2 ICACHE_IFETCH_STALL +PMC3 ILD_STALL_IQ_FULL + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L1I request rate PMC0/FIXC0 +L1I miss rate PMC1/FIXC0 +L1I miss ratio PMC1/PMC0 +L1I stalls PMC2 +L1I stall rate PMC2/FIXC0 +L1I queue full stalls PMC3 +L1I queue full stall rate PMC3/FIXC0 + +LONG +Formulas: +L1I request rate = ICACHE_ACCESSES / INSTR_RETIRED_ANY +L1I miss rate = ICACHE_MISSES / INSTR_RETIRED_ANY +L1I miss ratio = ICACHE_MISSES / ICACHE_ACCESSES +L1I stalls = ICACHE_IFETCH_STALL +L1I stall rate = ICACHE_IFETCH_STALL / INSTR_RETIRED_ANY +- +This group measures some L1 instruction cache metrics. diff --git a/collectors/likwid/groups/sandybridgeEP/L2.txt b/collectors/likwid/groups/sandybridgeEP/L2.txt new file mode 100644 index 0000000..1feb44c --- /dev/null +++ b/collectors/likwid/groups/sandybridgeEP/L2.txt @@ -0,0 +1,38 @@ +SHORT L2 cache bandwidth in MBytes/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 L1D_REPLACEMENT +PMC1 L1D_M_EVICT +PMC2 ICACHE_MISSES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L2D load bandwidth [MBytes/s] 1.0E-06*PMC0*64.0/time +L2D load data volume [GBytes] 1.0E-09*PMC0*64.0 +L2D evict bandwidth [MBytes/s] 1.0E-06*PMC1*64.0/time +L2D evict data volume [GBytes] 1.0E-09*PMC1*64.0 +L2 bandwidth [MBytes/s] 1.0E-06*(PMC0+PMC1+PMC2)*64.0/time +L2 data volume [GBytes] 1.0E-09*(PMC0+PMC1+PMC2)*64.0 + +LONG +Formulas: +L2D load bandwidth [MBytes/s] = 1.0E-06*L1D_REPLACEMENT*64.0/time +L2D load data volume [GBytes] = 1.0E-09*L1D_REPLACEMENT*64.0 +L2D evict bandwidth [MBytes/s] = 1.0E-06*L1D_M_EVICT*64.0/time +L2D evict data volume [GBytes] = 1.0E-09*L1D_M_EVICT*64.0 +L2 bandwidth [MBytes/s] = 1.0E-06*(L1D_REPLACEMENT+L1D_M_EVICT+ICACHE_MISSES)*64/time +L2 data volume [GBytes] = 1.0E-09*(L1D_REPLACEMENT+L1D_M_EVICT+ICACHE_MISSES)*64 +- +Profiling group to measure L2 cache bandwidth. The bandwidth is computed by the +number of cache line allocated in the L1 and the number of modified cache lines +evicted from the L1. The group also output total data volume transferred between +L2 and L1. Note that this bandwidth also includes data transfers due to a write +allocate load on a store miss in L1 and traffic caused by misses in the +L1 instruction cache. + diff --git a/collectors/likwid/groups/sandybridgeEP/L2CACHE.txt b/collectors/likwid/groups/sandybridgeEP/L2CACHE.txt new file mode 100644 index 0000000..fbc3745 --- /dev/null +++ b/collectors/likwid/groups/sandybridgeEP/L2CACHE.txt @@ -0,0 +1,34 @@ +SHORT L2 cache miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 L2_TRANS_ALL_REQUESTS +PMC1 L2_RQSTS_MISS + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L2 request rate PMC0/FIXC0 +L2 miss rate PMC1/FIXC0 +L2 miss ratio PMC1/PMC0 + +LONG +Formulas: +L2 request rate = L2_TRANS_ALL_REQUESTS/INSTR_RETIRED_ANY +L2 miss rate = L2_RQSTS_MISS/INSTR_RETIRED_ANY +L2 miss ratio = L2_RQSTS_MISS/L2_TRANS_ALL_REQUESTS +- +This group measures the locality of your data accesses with regard to the +L2 cache. L2 request rate tells you how data intensive your code is +or how many data accesses you have on average per instruction. +The L2 miss rate gives a measure how often it was necessary to get +cache lines from memory. And finally L2 miss ratio tells you how many of your +memory references required a cache line to be loaded from a higher level. +While the data cache miss rate might be given by your algorithm you should +try to get data cache miss ratio as low as possible by increasing your cache reuse. + + diff --git a/collectors/likwid/groups/sandybridgeEP/L3.txt b/collectors/likwid/groups/sandybridgeEP/L3.txt new file mode 100644 index 0000000..f63a918 --- /dev/null +++ b/collectors/likwid/groups/sandybridgeEP/L3.txt @@ -0,0 +1,36 @@ +SHORT L3 cache bandwidth in MBytes/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 L2_LINES_IN_ALL +PMC1 L2_TRANS_L2_WB + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L3 load bandwidth [MBytes/s] 1.0E-06*PMC0*64.0/time +L3 load data volume [GBytes] 1.0E-09*PMC0*64.0 +L3 evict bandwidth [MBytes/s] 1.0E-06*PMC1*64.0/time +L3 evict data volume [GBytes] 1.0E-09*PMC1*64.0 +L3 bandwidth [MBytes/s] 1.0E-06*(PMC0+PMC1)*64.0/time +L3 data volume [GBytes] 1.0E-09*(PMC0+PMC1)*64.0 + +LONG +Formulas: +L3 load bandwidth [MBytes/s] = 1.0E-06*L2_LINES_IN_ALL*64.0/time +L3 load data volume [GBytes] = 1.0E-09*L2_LINES_IN_ALL*64.0 +L3 evict bandwidth [MBytes/s] = 1.0E-06*L2_TRANS_L2_WB*64.0/time +L3 evict data volume [GBytes] = 1.0E-09*L2_TRANS_L2_WB*64.0 +L3 bandwidth [MBytes/s] = 1.0E-06*(L2_LINES_IN_ALL+L2_TRANS_L2_WB)*64/time +L3 data volume [GBytes] = 1.0E-09*(L2_LINES_IN_ALL+L2_TRANS_L2_WB)*64 +- +Profiling group to measure L3 cache bandwidth. The bandwidth is computed by the +number of cache line allocated in the L2 and the number of modified cache lines +evicted from the L2. This group also output data volume transferred between the +L3 and measured cores L2 caches. Note that this bandwidth also includes data +transfers due to a write allocate load on a store miss in L2. + diff --git a/collectors/likwid/groups/sandybridgeEP/L3CACHE.txt b/collectors/likwid/groups/sandybridgeEP/L3CACHE.txt new file mode 100644 index 0000000..3dbb6cc --- /dev/null +++ b/collectors/likwid/groups/sandybridgeEP/L3CACHE.txt @@ -0,0 +1,36 @@ +SHORT L3 cache miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0:MATCH0=0x0081:MATCH1=0x3fffc0 OFFCORE_RESPONSE_0_OPTIONS +PMC1:MATCH0=0x0081:MATCH1=0x1 OFFCORE_RESPONSE_1_OPTIONS +PMC2 L1D_REPLACEMENT + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L3 request rate PMC1/FIXC0 +L3 miss rate PMC0/FIXC0 +L3 miss ratio PMC0/PMC1 + +LONG +Formulas: +L3 request rate = OFFCORE_RESPONSE_1_OPTIONS:MATCH0=0x0081:MATCH1=0x1/INSTR_RETIRED_ANY +L3 miss rate = OFFCORE_RESPONSE_0_OPTIONS:MATCH0=0x0081:MATCH1=0x3fffc0/INSTR_RETIRED_ANY +L3 miss ratio = OFFCORE_RESPONSE_0_OPTIONS:MATCH0=0x0081:MATCH1=0x3fffc0/OFFCORE_RESPONSE_1_OPTIONS:MATCH0=0x0081:MATCH1=0x1 +- +This group measures the locality of your data accesses with regard to the +L3 cache. L3 request rate tells you how data intensive your code is +or how many data accesses you have on average per instruction. +The L3 miss rate gives a measure how often it was necessary to get +cache lines from L3 compared to all loaded cache lines in L1. +And finally L3 miss ratio tells you how many of your +memory references required a cache line to be loaded from a higher level. +While the data cache miss rate might be given by your algorithm you should +try to get data cache miss ratio as low as possible by increasing your cache reuse. + + diff --git a/collectors/likwid/groups/sandybridgeEP/MEM.txt b/collectors/likwid/groups/sandybridgeEP/MEM.txt new file mode 100644 index 0000000..0be0645 --- /dev/null +++ b/collectors/likwid/groups/sandybridgeEP/MEM.txt @@ -0,0 +1,40 @@ +SHORT Main memory bandwidth in MBytes/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +MBOX0C0 CAS_COUNT_RD +MBOX0C1 CAS_COUNT_WR +MBOX1C0 CAS_COUNT_RD +MBOX1C1 CAS_COUNT_WR +MBOX2C0 CAS_COUNT_RD +MBOX2C1 CAS_COUNT_WR +MBOX3C0 CAS_COUNT_RD +MBOX3C1 CAS_COUNT_WR + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Memory read bandwidth [MBytes/s] 1.0E-06*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0)*64.0/time +Memory read data volume [GBytes] 1.0E-09*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0)*64.0 +Memory write bandwidth [MBytes/s] 1.0E-06*(MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1)*64.0/time +Memory write data volume [GBytes] 1.0E-09*(MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1)*64.0 +Memory bandwidth [MBytes/s] 1.0E-06*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1)*64.0/time +Memory data volume [GBytes] 1.0E-09*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1)*64.0 + +LONG +Formulas: +Memory read bandwidth [MBytes/s] = 1.0E-06*(SUM(MBOXxC0))*64.0/time +Memory read data volume [GBytes] = 1.0E-09*(SUM(MBOXxC0))*64.0 +Memory write bandwidth [MBytes/s] = 1.0E-06*(SUM(MBOXxC1))*64.0/time +Memory write data volume [GBytes] = 1.0E-09*(SUM(MBOXxC1))*64.0 +Memory bandwidth [MBytes/s] = 1.0E-06*(SUM(MBOXxC0)+SUM(MBOXxC1))*64.0/time +Memory data volume [GBytes] = 1.0E-09*(SUM(MBOXxC0)+SUM(MBOXxC1))*64.0 +- +Profiling group to measure memory bandwidth drawn by all cores of a socket. +Since this group is based on Uncore events it is only possible to measure on a +per socket base. Also outputs total data volume transferred from main memory. + diff --git a/collectors/likwid/groups/sandybridgeEP/MEM_DP.txt b/collectors/likwid/groups/sandybridgeEP/MEM_DP.txt new file mode 100644 index 0000000..f2d68ba --- /dev/null +++ b/collectors/likwid/groups/sandybridgeEP/MEM_DP.txt @@ -0,0 +1,66 @@ +SHORT Overview of arithmetic and main memory performance + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PWR0 PWR_PKG_ENERGY +PWR3 PWR_DRAM_ENERGY +PMC0 FP_COMP_OPS_EXE_SSE_FP_PACKED_DOUBLE +PMC1 FP_COMP_OPS_EXE_SSE_FP_SCALAR_DOUBLE +PMC2 SIMD_FP_256_PACKED_DOUBLE +MBOX0C0 CAS_COUNT_RD +MBOX0C1 CAS_COUNT_WR +MBOX1C0 CAS_COUNT_RD +MBOX1C1 CAS_COUNT_WR +MBOX2C0 CAS_COUNT_RD +MBOX2C1 CAS_COUNT_WR +MBOX3C0 CAS_COUNT_RD +MBOX3C1 CAS_COUNT_WR + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Energy [J] PWR0 +Power [W] PWR0/time +Energy DRAM [J] PWR3 +Power DRAM [W] PWR3/time +MFLOP/s 1.0E-06*(PMC0*2.0+PMC1+PMC2*4.0)/time +AVX [MFLOP/s] 1.0E-06*(PMC2*4.0)/time +Packed [MUOPS/s] 1.0E-06*(PMC0+PMC2)/time +Scalar [MUOPS/s] 1.0E-06*PMC1/time +Memory read bandwidth [MBytes/s] 1.0E-06*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0)*64.0/time +Memory read data volume [GBytes] 1.0E-09*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0)*64.0 +Memory write bandwidth [MBytes/s] 1.0E-06*(MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1)*64.0/time +Memory write data volume [GBytes] 1.0E-09*(MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1)*64.0 +Memory bandwidth [MBytes/s] 1.0E-06*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1)*64.0/time +Memory data volume [GBytes] 1.0E-09*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1)*64.0 +Operational intensity (PMC0*2.0+PMC1+PMC2*4.0)/((MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1)*64.0) + +LONG +Formulas: +Power [W] = PWR_PKG_ENERGY/runtime +Power DRAM [W] = PWR_DRAM_ENERGY/runtime +MFLOP/s = 1.0E-06*(FP_COMP_OPS_EXE_SSE_FP_PACKED*2+FP_COMP_OPS_EXE_SSE_FP_SCALAR+SIMD_FP_256_PACKED_DOUBLE*4)/runtime +AVX [MFLOP/s] = 1.0E-06*(SIMD_FP_256_PACKED_DOUBLE*4)/runtime +Packed [MUOPS/s] = 1.0E-06*(FP_COMP_OPS_EXE_SSE_FP_PACKED_DOUBLE+SIMD_FP_256_PACKED_DOUBLE)/runtime +Scalar [MUOPS/s] = 1.0E-06*FP_COMP_OPS_EXE_SSE_FP_SCALAR_DOUBLE/runtime +Memory read bandwidth [MBytes/s] = 1.0E-06*(SUM(MBOXxC0))*64.0/time +Memory read data volume [GBytes] = 1.0E-09*(SUM(MBOXxC0))*64.0 +Memory write bandwidth [MBytes/s] = 1.0E-06*(SUM(MBOXxC1))*64.0/time +Memory write data volume [GBytes] = 1.0E-09*(SUM(MBOXxC1))*64.0 +Memory bandwidth [MBytes/s] = 1.0E-06*(SUM(MBOXxC0)+SUM(MBOXxC1))*64.0/time +Memory data volume [GBytes] = 1.0E-09*(SUM(MBOXxC0)+SUM(MBOXxC1))*64.0 +Operational intensity = (FP_COMP_OPS_EXE_SSE_FP_PACKED*2+FP_COMP_OPS_EXE_SSE_FP_SCALAR+SIMD_FP_256_PACKED_DOUBLE*4)/((SUM(MBOXxC0)+SUM(MBOXxC1))*64.0) +-- +Profiling group to measure memory bandwidth drawn by all cores of a socket. +Since this group is based on Uncore events it is only possible to measure on +a per socket base. Also outputs total data volume transferred from main memory. +SSE scalar and packed double precision FLOP rates. Also reports on packed AVX +32b instructions. Please note that the current FLOP measurements on SandyBridge +are potentially wrong. So you cannot trust these counters at the moment! +The operational intensity is calculated using the FP values of the cores and the +memory data volume of the whole socket. The actual operational intensity for +multiple CPUs can be found in the statistics table in the Sum column. diff --git a/collectors/likwid/groups/sandybridgeEP/MEM_SP.txt b/collectors/likwid/groups/sandybridgeEP/MEM_SP.txt new file mode 100644 index 0000000..955cdc4 --- /dev/null +++ b/collectors/likwid/groups/sandybridgeEP/MEM_SP.txt @@ -0,0 +1,66 @@ +SHORT Overview of arithmetic and main memory performance + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PWR0 PWR_PKG_ENERGY +PWR3 PWR_DRAM_ENERGY +PMC0 FP_COMP_OPS_EXE_SSE_FP_PACKED_SINGLE +PMC1 FP_COMP_OPS_EXE_SSE_FP_SCALAR_SINGLE +PMC2 SIMD_FP_256_PACKED_SINGLE +MBOX0C0 CAS_COUNT_RD +MBOX0C1 CAS_COUNT_WR +MBOX1C0 CAS_COUNT_RD +MBOX1C1 CAS_COUNT_WR +MBOX2C0 CAS_COUNT_RD +MBOX2C1 CAS_COUNT_WR +MBOX3C0 CAS_COUNT_RD +MBOX3C1 CAS_COUNT_WR + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Energy [J] PWR0 +Power [W] PWR0/time +Energy DRAM [J] PWR3 +Power DRAM [W] PWR3/time +MFLOP/s 1.0E-06*(PMC0*4.0+PMC1+PMC2*8.0)/time +AVX [MFLOP/s] 1.0E-06*(PMC2*8.0)/time +Packed [MUOPS/s] 1.0E-06*(PMC0+PMC2)/time +Scalar [MUOPS/s] 1.0E-06*PMC1/time +Memory read bandwidth [MBytes/s] 1.0E-06*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0)*64.0/time +Memory read data volume [GBytes] 1.0E-09*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0)*64.0 +Memory write bandwidth [MBytes/s] 1.0E-06*(MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1)*64.0/time +Memory write data volume [GBytes] 1.0E-09*(MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1)*64.0 +Memory bandwidth [MBytes/s] 1.0E-06*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1)*64.0/time +Memory data volume [GBytes] 1.0E-09*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1)*64.0 +Operational intensity (PMC0*4.0+PMC1+PMC2*8.0)/((MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1)*64.0) + +LONG +Formulas: +Power [W] = PWR_PKG_ENERGY/runtime +Power DRAM [W] = PWR_DRAM_ENERGY/runtime +MFLOP/s = 1.0E-06*(FP_COMP_OPS_EXE_SSE_FP_PACKED*4+FP_COMP_OPS_EXE_SSE_FP_SCALAR+SIMD_FP_256_PACKED_SINGLE*8)/runtime +AVX [MFLOP/s] = 1.0E-06*(SIMD_FP_256_PACKED_SINGLE*8)/runtime +Packed [MUOPS/s] = 1.0E-06*(FP_COMP_OPS_EXE_SSE_FP_PACKED_SINGLE+SIMD_FP_256_PACKED_SINGLE)/runtime +Scalar [MUOPS/s] = 1.0E-06*FP_COMP_OPS_EXE_SSE_FP_SCALAR_SINGLE/runtime +Memory read bandwidth [MBytes/s] = 1.0E-06*(SUM(MBOXxC0))*64.0/time +Memory read data volume [GBytes] = 1.0E-09*(SUM(MBOXxC0))*64.0 +Memory write bandwidth [MBytes/s] = 1.0E-06*(SUM(MBOXxC1))*64.0/time +Memory write data volume [GBytes] = 1.0E-09*(SUM(MBOXxC1))*64.0 +Memory bandwidth [MBytes/s] = 1.0E-06*(SUM(MBOXxC0)+SUM(MBOXxC1))*64.0/time +Memory data volume [GBytes] = 1.0E-09*(SUM(MBOXxC0)+SUM(MBOXxC1))*64.0 +Operational intensity = (FP_COMP_OPS_EXE_SSE_FP_PACKED*4+FP_COMP_OPS_EXE_SSE_FP_SCALAR+SIMD_FP_256_PACKED_SINGLE*8)/((SUM(MBOXxC0)+SUM(MBOXxC1))*64.0) +-- +Profiling group to measure memory bandwidth drawn by all cores of a socket. +Since this group is based on Uncore events it is only possible to measure on +a per socket base. Also outputs total data volume transferred from main memory. +SSE scalar and packed single precision FLOP rates. Also reports on packed AVX +32b instructions. Please note that the current FLOP measurements on SandyBridge +are potentially wrong. So you cannot trust these counters at the moment! +The operational intensity is calculated using the FP values of the cores and the +memory data volume of the whole socket. The actual operational intensity for +multiple CPUs can be found in the statistics table in the Sum column. diff --git a/collectors/likwid/groups/sandybridgeEP/NUMA.txt b/collectors/likwid/groups/sandybridgeEP/NUMA.txt new file mode 100644 index 0000000..41fbe62 --- /dev/null +++ b/collectors/likwid/groups/sandybridgeEP/NUMA.txt @@ -0,0 +1,33 @@ +SHORT Local and remote memory accesses + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 OFFCORE_RESPONSE_0_LOCAL_DRAM +PMC1 OFFCORE_RESPONSE_1_REMOTE_DRAM + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Local DRAM data volume [GByte] 1.E-09*PMC0*64 +Local DRAM bandwidth [MByte/s] 1.E-06*(PMC0*64)/time +Remote DRAM data volume [GByte] 1.E-09*PMC1*64 +Remote DRAM bandwidth [MByte/s] 1.E-06*(PMC1*64)/time +Memory data volume [GByte] 1.E-09*(PMC0+PMC1)*64 +Memory bandwidth [MByte/s] 1.E-06*((PMC0+PMC1)*64)/time + +LONG +Formulas: +CPI = CPU_CLK_UNHALTED_CORE/INSTR_RETIRED_ANY +Local DRAM data volume [GByte] = 1.E-09*OFFCORE_RESPONSE_0_LOCAL_DRAM*64 +Local DRAM bandwidth [MByte/s] = 1.E-06*(OFFCORE_RESPONSE_0_LOCAL_DRAM*64)/time +Remote DRAM data volume [GByte] = 1.E-09*OFFCORE_RESPONSE_1_REMOTE_DRAM*64 +Remote DRAM bandwidth [MByte/s] = 1.E-06*(OFFCORE_RESPONSE_1_REMOTE_DRAM*64)/time +Memory data volume [GByte] = 1.E-09*(OFFCORE_RESPONSE_0_LOCAL_DRAM+OFFCORE_RESPONSE_1_REMOTE_DRAM)*64 +Memory bandwidth [MByte/s] = 1.E-06*((OFFCORE_RESPONSE_0_LOCAL_DRAM+OFFCORE_RESPONSE_1_REMOTE_DRAM)*64)/time +-- +This performance group measures the data traffic of CPU cores to local and remote +memory. diff --git a/collectors/likwid/groups/sandybridgeEP/PORT_USAGE.txt b/collectors/likwid/groups/sandybridgeEP/PORT_USAGE.txt new file mode 100644 index 0000000..d509607 --- /dev/null +++ b/collectors/likwid/groups/sandybridgeEP/PORT_USAGE.txt @@ -0,0 +1,40 @@ +SHORT Execution port utilization + +REQUIRE_NOHT + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 UOPS_DISPATCHED_PORT_PORT_0 +PMC1 UOPS_DISPATCHED_PORT_PORT_1 +PMC2 UOPS_DISPATCHED_PORT_PORT_2 +PMC3 UOPS_DISPATCHED_PORT_PORT_3 +PMC4 UOPS_DISPATCHED_PORT_PORT_4 +PMC5 UOPS_DISPATCHED_PORT_PORT_5 + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Port0 usage ratio PMC0/(PMC0+PMC1+PMC2+PMC3+PMC4+PMC5) +Port1 usage ratio PMC1/(PMC0+PMC1+PMC2+PMC3+PMC4+PMC5) +Port2 usage ratio PMC2/(PMC0+PMC1+PMC2+PMC3+PMC4+PMC5) +Port3 usage ratio PMC3/(PMC0+PMC1+PMC2+PMC3+PMC4+PMC5) +Port4 usage ratio PMC4/(PMC0+PMC1+PMC2+PMC3+PMC4+PMC5) +Port5 usage ratio PMC5/(PMC0+PMC1+PMC2+PMC3+PMC4+PMC5) + +LONG +Formulas: +Port0 usage ratio = UOPS_DISPATCHED_PORT_PORT_0/SUM(UOPS_DISPATCHED_PORT_PORT_*) +Port1 usage ratio = UOPS_DISPATCHED_PORT_PORT_1/SUM(UOPS_DISPATCHED_PORT_PORT_*) +Port2 usage ratio = UOPS_DISPATCHED_PORT_PORT_2/SUM(UOPS_DISPATCHED_PORT_PORT_*) +Port3 usage ratio = UOPS_DISPATCHED_PORT_PORT_3/SUM(UOPS_DISPATCHED_PORT_PORT_*) +Port4 usage ratio = UOPS_DISPATCHED_PORT_PORT_4/SUM(UOPS_DISPATCHED_PORT_PORT_*) +Port5 usage ratio = UOPS_DISPATCHED_PORT_PORT_5/SUM(UOPS_DISPATCHED_PORT_PORT_*) +- +This group measures the execution port utilization in a CPU core. The group can +only be measured when HyperThreading is disabled because only then each CPU core +can program eight counters. diff --git a/collectors/likwid/groups/sandybridgeEP/QPI.txt b/collectors/likwid/groups/sandybridgeEP/QPI.txt new file mode 100644 index 0000000..320614f --- /dev/null +++ b/collectors/likwid/groups/sandybridgeEP/QPI.txt @@ -0,0 +1,35 @@ +SHORT QPI traffic between sockets + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +SBOX0C0 DIRECT2CORE_SUCCESS +SBOX0C1 RXL_FLITS_G1_DRS_DATA +SBOX0C2 RXL_FLITS_G2_NCB_DATA +SBOX1C0 DIRECT2CORE_SUCCESS +SBOX1C1 RXL_FLITS_G1_DRS_DATA +SBOX1C2 RXL_FLITS_G2_NCB_DATA + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Received bandwidth from QPI [MBytes/s] 1.0E-06*(SBOX0C1+SBOX0C2+SBOX1C1+SBOX1C2)*8/time +Received data volume from QPI [GBytes] 1.0E-09*(SBOX0C1+SBOX0C2+SBOX1C1+SBOX1C2)*8 +Bandwidth QPI to LLC [MBytes/s] 1.0E-06*(SBOX0C0+SBOX1C0)*64/time +Data volume QPI to LLC [GBytes] 1.0E-09*(SBOX0C0+SBOX1C0)*64 +Bandwidth QPI to HA or IIO [MBytes/s] 1.0E-06*(((SBOX0C1+SBOX0C2+SBOX1C1+SBOX1C2)*8)-((SBOX0C0+SBOX1C0)*64))/time +Data volume QPI to HA or IIO [GBytes] 1.0E-09*(((SBOX0C1+SBOX0C2+SBOX1C1+SBOX1C2)*8)-((SBOX0C0+SBOX1C0)*64)) + +LONG +Formulas: +Received bandwidth from QPI [MBytes/s] = 1.0E-06*(sum(RXL_FLITS_G1_DRS_DATA)+sum(RXL_FLITS_G2_NCB_DATA))*8/time +Received data volume from QPI [GBytes] = 1.0E-09*(sum(RXL_FLITS_G1_DRS_DATA)+sum(RXL_FLITS_G2_NCB_DATA))*8 +Bandwidth QPI to LLC [MBytes/s] = 1.0E-06*(sum(DIRECT2CORE_SUCCESS))*64/time +Data volume QPI to LLC [GBytes] = 1.0E-09*(sum(DIRECT2CORE_SUCCESS))*64 +Bandwidth QPI to HA or IIO [MBytes/s] = 1.0E-06*(((sum(RXL_FLITS_G1_DRS_DATA)+sum(RXL_FLITS_G2_NCB_DATA))*8)-((sum(DIRECT2CORE_SUCCESS))*64))/time +Data volume QPI to HA or IIO [GBytes] = 1.0E-09*(((sum(RXL_FLITS_G1_DRS_DATA)+sum(RXL_FLITS_G2_NCB_DATA))*8)-((sum(DIRECT2CORE_SUCCESS))*64)) +- +Profiling group to measure traffic on the QPI. diff --git a/collectors/likwid/groups/sandybridgeEP/RECOVERY.txt b/collectors/likwid/groups/sandybridgeEP/RECOVERY.txt new file mode 100644 index 0000000..7928ee4 --- /dev/null +++ b/collectors/likwid/groups/sandybridgeEP/RECOVERY.txt @@ -0,0 +1,22 @@ +SHORT Recovery duration + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 INT_MISC_RECOVERY_CYCLES +PMC1 INT_MISC_RECOVERY_COUNT + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Avg. recovery duration PMC0/PMC1 + +LONG +Formulas: +Avg. recovery duration = INT_MISC_RECOVERY_CYCLES/INT_MISC_RECOVERY_COUNT +- +This group measures the duration of recoveries after SSE exception, memory +disambiguation, etc... diff --git a/collectors/likwid/groups/sandybridgeEP/TLB_DATA.txt b/collectors/likwid/groups/sandybridgeEP/TLB_DATA.txt new file mode 100644 index 0000000..8d94e05 --- /dev/null +++ b/collectors/likwid/groups/sandybridgeEP/TLB_DATA.txt @@ -0,0 +1,35 @@ +SHORT L2 data TLB miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 DTLB_LOAD_MISSES_CAUSES_A_WALK +PMC1 DTLB_STORE_MISSES_CAUSES_A_WALK +PMC2 DTLB_LOAD_MISSES_WALK_DURATION +PMC3 DTLB_STORE_MISSES_WALK_DURATION + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L1 DTLB load misses PMC0 +L1 DTLB load miss rate PMC0/FIXC0 +L1 DTLB load miss duration [Cyc] PMC2/PMC0 +L1 DTLB store misses PMC1 +L1 DTLB store miss rate PMC1/FIXC0 +L1 DTLB store miss duration [Cyc] PMC3/PMC1 + +LONG +Formulas: +L1 DTLB load misses = DTLB_LOAD_MISSES_CAUSES_A_WALK +L1 DTLB load miss rate = DTLB_LOAD_MISSES_CAUSES_A_WALK / INSTR_RETIRED_ANY +L1 DTLB load miss duration [Cyc] = DTLB_LOAD_MISSES_WALK_DURATION / DTLB_LOAD_MISSES_CAUSES_A_WALK +L1 DTLB store misses = DTLB_STORE_MISSES_CAUSES_A_WALK +L1 DTLB store miss rate = DTLB_STORE_MISSES_CAUSES_A_WALK / INSTR_RETIRED_ANY +L1 DTLB store miss duration [Cyc] = DTLB_STORE_MISSES_WALK_DURATION / DTLB_STORE_MISSES_CAUSES_A_WALK +- +The DTLB load and store miss rates gives a measure how often a TLB miss occurred +per instruction. The duration measures the time in cycles how long a walk did take. + diff --git a/collectors/likwid/groups/sandybridgeEP/TLB_INSTR.txt b/collectors/likwid/groups/sandybridgeEP/TLB_INSTR.txt new file mode 100644 index 0000000..235d977 --- /dev/null +++ b/collectors/likwid/groups/sandybridgeEP/TLB_INSTR.txt @@ -0,0 +1,28 @@ +SHORT L1 Instruction TLB miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 ITLB_MISSES_CAUSES_A_WALK +PMC1 ITLB_MISSES_WALK_DURATION + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L1 ITLB misses PMC0 +L1 ITLB miss rate PMC0/FIXC0 +L1 ITLB miss duration [Cyc] PMC1/PMC0 + + +LONG +Formulas: +L1 ITLB misses = ITLB_MISSES_CAUSES_A_WALK +L1 ITLB miss rate = ITLB_MISSES_CAUSES_A_WALK / INSTR_RETIRED_ANY +L1 ITLB miss duration [Cyc] = ITLB_MISSES_WALK_DURATION / ITLB_MISSES_CAUSES_A_WALK +- +The ITLB miss rates gives a measure how often a TLB miss occurred +per instruction. The duration measures the time in cycles how long a walk did take. + diff --git a/collectors/likwid/groups/sandybridgeEP/TMA.txt b/collectors/likwid/groups/sandybridgeEP/TMA.txt new file mode 100644 index 0000000..afb4126 --- /dev/null +++ b/collectors/likwid/groups/sandybridgeEP/TMA.txt @@ -0,0 +1,48 @@ +SHORT Top down cycle allocation + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 UOPS_ISSUED_ANY +PMC1 UOPS_RETIRED_RETIRE_SLOTS +PMC2 IDQ_UOPS_NOT_DELIVERED_CORE +PMC3 INT_MISC_RECOVERY_CYCLES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +IPC FIXC0/FIXC1 +Total Slots 4*FIXC1 +Slots Retired PMC1 +Fetch Bubbles PMC2 +Recovery Bubbles 4*PMC3 +Front End [%] PMC2/(4*FIXC1)*100 +Speculation [%] (PMC0-PMC1+(4*PMC3))/(4*FIXC1)*100 +Retiring [%] PMC1/(4*FIXC1)*100 +Back End [%] (1-((PMC2+PMC0+(4*PMC3))/(4*FIXC1)))*100 + +LONG +Formulas: +Total Slots = 4*CPU_CLK_UNHALTED_CORE +Slots Retired = UOPS_RETIRED_RETIRE_SLOTS +Fetch Bubbles = IDQ_UOPS_NOT_DELIVERED_CORE +Recovery Bubbles = 4*INT_MISC_RECOVERY_CYCLES +Front End [%] = IDQ_UOPS_NOT_DELIVERED_CORE/(4*CPU_CLK_UNHALTED_CORE)*100 +Speculation [%] = (UOPS_ISSUED_ANY-UOPS_RETIRED_RETIRE_SLOTS+(4*INT_MISC_RECOVERY_CYCLES))/(4*CPU_CLK_UNHALTED_CORE)*100 +Retiring [%] = UOPS_RETIRED_RETIRE_SLOTS/(4*CPU_CLK_UNHALTED_CORE)*100 +Back End [%] = (1-((IDQ_UOPS_NOT_DELIVERED_CORE+UOPS_ISSUED_ANY+(4*INT_MISC_RECOVERY_CYCLES))/(4*CPU_CLK_UNHALTED_CORE)))*100 +-- +This performance group measures cycles to determine percentage of time spent in +front end, back end, retiring and speculation. These metrics are published and +verified by Intel. Further information: +Webpage describing Top-Down Method and its usage in Intel vTune: +https://software.intel.com/en-us/vtune-amplifier-help-tuning-applications-using-a-top-down-microarchitecture-analysis-method +Paper by Yasin Ahmad: +https://sites.google.com/site/analysismethods/yasin-pubs/TopDown-Yasin-ISPASS14.pdf?attredirects=0 +Slides by Yasin Ahmad: +http://www.cs.technion.ac.il/~erangi/TMA_using_Linux_perf__Ahmad_Yasin.pdf +The performance group was originally published here: +http://perf.mvermeulen.com/2018/04/14/top-down-performance-counter-analysis-part-1-likwid/ diff --git a/collectors/likwid/groups/sandybridgeEP/UOPS.txt b/collectors/likwid/groups/sandybridgeEP/UOPS.txt new file mode 100644 index 0000000..a4d35d8 --- /dev/null +++ b/collectors/likwid/groups/sandybridgeEP/UOPS.txt @@ -0,0 +1,32 @@ +SHORT UOPs execution info + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 UOPS_ISSUED_ANY +PMC1 UOPS_EXECUTED_THREAD +PMC2 UOPS_RETIRED_ALL + + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Issued UOPs PMC0 +Executed UOPs PMC1 +Retired UOPs PMC2 + +LONG +Formulas: +Issued UOPs = UOPS_ISSUED_ANY +Executed UOPs = UOPS_EXECUTED_THREAD +Retired UOPs = UOPS_RETIRED_ALL +- +This group returns information about the instruction pipeline. It measures the +issued, executed and retired uOPs and returns the number of uOPs which were issued +but not executed as well as the number of uOPs which were executed but never retired. +The executed but not retired uOPs commonly come from speculatively executed branches. + diff --git a/collectors/likwid/groups/sandybridgeEP/UOPS_EXEC.txt b/collectors/likwid/groups/sandybridgeEP/UOPS_EXEC.txt new file mode 100644 index 0000000..7042df7 --- /dev/null +++ b/collectors/likwid/groups/sandybridgeEP/UOPS_EXEC.txt @@ -0,0 +1,31 @@ +SHORT UOPs execution + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 UOPS_EXECUTED_USED_CYCLES +PMC1 UOPS_EXECUTED_STALL_CYCLES +PMC2 CPU_CLOCK_UNHALTED_TOTAL_CYCLES +PMC3:EDGEDETECT UOPS_EXECUTED_STALL_CYCLES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Used cycles ratio [%] 100*PMC0/PMC2 +Unused cycles ratio [%] 100*PMC1/PMC2 +Avg stall duration [cycles] PMC1/PMC3:EDGEDETECT + + +LONG +Formulas: +Used cycles ratio [%] = 100*UOPS_EXECUTED_USED_CYCLES/CPU_CLK_UNHALTED_CORE +Unused cycles ratio [%] = 100*UOPS_EXECUTED_STALL_CYCLES/CPU_CLK_UNHALTED_CORE +Avg stall duration [cycles] = UOPS_EXECUTED_STALL_CYCLES/UOPS_EXECUTED_STALL_CYCLES:EDGEDETECT +- +This performance group returns the ratios of used and unused cycles regarding +the execution stage in the pipeline. Used cycles are all cycles where uOPs are +executed while unused cycles refer to pipeline stalls. Moreover, the group +calculates the average stall duration in cycles. diff --git a/collectors/likwid/groups/sandybridgeEP/UOPS_ISSUE.txt b/collectors/likwid/groups/sandybridgeEP/UOPS_ISSUE.txt new file mode 100644 index 0000000..9aac923 --- /dev/null +++ b/collectors/likwid/groups/sandybridgeEP/UOPS_ISSUE.txt @@ -0,0 +1,31 @@ +SHORT UOPs issueing + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 UOPS_ISSUED_USED_CYCLES +PMC1 UOPS_ISSUED_STALL_CYCLES +PMC2 CPU_CLOCK_UNHALTED_TOTAL_CYCLES +PMC3:EDGEDETECT UOPS_ISSUED_STALL_CYCLES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Used cycles ratio [%] 100*PMC0/PMC2 +Unused cycles ratio [%] 100*PMC1/PMC2 +Avg stall duration [cycles] PMC1/PMC3:EDGEDETECT + + +LONG +Formulas: +Used cycles ratio [%] = 100*UOPS_ISSUED_USED_CYCLES/CPU_CLK_UNHALTED_CORE +Unused cycles ratio [%] = 100*UOPS_ISSUED_STALL_CYCLES/CPU_CLK_UNHALTED_CORE +Avg stall duration [cycles] = UOPS_ISSUED_STALL_CYCLES/UOPS_ISSUED_STALL_CYCLES:EDGEDETECT +- +This performance group returns the ratios of used and unused cycles regarding +the issue stage in the pipeline. Used cycles are all cycles where uOPs are +issued while unused cycles refer to pipeline stalls. Moreover, the group +calculates the average stall duration in cycles. diff --git a/collectors/likwid/groups/sandybridgeEP/UOPS_RETIRE.txt b/collectors/likwid/groups/sandybridgeEP/UOPS_RETIRE.txt new file mode 100644 index 0000000..0f37585 --- /dev/null +++ b/collectors/likwid/groups/sandybridgeEP/UOPS_RETIRE.txt @@ -0,0 +1,31 @@ +SHORT UOPs retirement + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 UOPS_RETIRED_USED_CYCLES +PMC1 UOPS_RETIRED_STALL_CYCLES +PMC2 CPU_CLOCK_UNHALTED_TOTAL_CYCLES +PMC3:EDGEDETECT UOPS_RETIRED_STALL_CYCLES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Used cycles ratio [%] 100*PMC0/PMC2 +Unused cycles ratio [%] 100*PMC1/PMC2 +Avg stall duration [cycles] PMC1/PMC3:EDGEDETECT + + +LONG +Formulas: +Used cycles ratio [%] = 100*UOPS_RETIRED_USED_CYCLES/CPU_CLK_UNHALTED_CORE +Unused cycles ratio [%] = 100*UOPS_RETIRED_STALL_CYCLES/CPU_CLK_UNHALTED_CORE +Avg stall duration [cycles] = UOPS_RETIRED_STALL_CYCLES/UOPS_RETIRED_STALL_CYCLES:EDGEDETECT +- +This performance group returns the ratios of used and unused cycles regarding +the retirement stage in the pipeline (re-order buffer). Used cycles are all +cycles where uOPs are retired while unused cycles refer to pipeline stalls. +Moreover, the group calculates the average stall duration in cycles. diff --git a/collectors/likwid/groups/silvermont/BRANCH.txt b/collectors/likwid/groups/silvermont/BRANCH.txt new file mode 100644 index 0000000..b8d41b2 --- /dev/null +++ b/collectors/likwid/groups/silvermont/BRANCH.txt @@ -0,0 +1,31 @@ +SHORT Branch prediction miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 BR_INST_RETIRED_ALL_BRANCHES +PMC1 BR_MISP_RETIRED_ALL_BRANCHES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Branch rate PMC0/FIXC0 +Branch misprediction rate PMC1/FIXC0 +Branch misprediction ratio PMC1/PMC0 +Instructions per branch FIXC0/PMC0 + +LONG +Formulas: +Branch rate = BR_INST_RETIRED_ALL_BRANCHES/INSTR_RETIRED_ANY +Branch misprediction rate = BR_MISP_RETIRED_ALL_BRANCHES/INSTR_RETIRED_ANY +Branch misprediction ratio = BR_MISP_RETIRED_ALL_BRANCHES/BR_INST_RETIRED_ALL_BRANCHES +Instructions per branch = INSTR_RETIRED_ANY/BR_INST_RETIRED_ALL_BRANCHES +- +The rates state how often on average a branch or a mispredicted branch occurred +per instruction retired in total. The branch misprediction ratio sets directly +into relation what ratio of all branch instruction where mispredicted. +Instructions per branch is 1/branch rate. + diff --git a/collectors/likwid/groups/silvermont/CLOCK.txt b/collectors/likwid/groups/silvermont/CLOCK.txt new file mode 100644 index 0000000..b2174c8 --- /dev/null +++ b/collectors/likwid/groups/silvermont/CLOCK.txt @@ -0,0 +1,23 @@ +SHORT Power and Energy consumption + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PWR0 PWR_PKG_ENERGY + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Energy [J] PWR0 +Power [W] PWR0/time + +LONG +Formulas: +Power = PWR_PKG_ENERGY / time +- +Silvermont implements the new RAPL interface. This interface enables to +monitor the consumed energy on the package (socket) level. + diff --git a/collectors/likwid/groups/silvermont/DATA.txt b/collectors/likwid/groups/silvermont/DATA.txt new file mode 100644 index 0000000..61a915b --- /dev/null +++ b/collectors/likwid/groups/silvermont/DATA.txt @@ -0,0 +1,22 @@ +SHORT Load to store ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 MEM_UOPS_RETIRED_ALL_LOADS +PMC1 MEM_UOPS_RETIRED_ALL_STORES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Load to store ratio PMC0/PMC1 + +LONG +Formulas: +Load to store ratio = MEM_UOPS_RETIRED_ALL_LOADS/MEM_UOPS_RETIRED_ALL_STORES +- +This is a metric to determine your load to store ratio. + diff --git a/collectors/likwid/groups/silvermont/DIVIDE.txt b/collectors/likwid/groups/silvermont/DIVIDE.txt new file mode 100644 index 0000000..f82fc59 --- /dev/null +++ b/collectors/likwid/groups/silvermont/DIVIDE.txt @@ -0,0 +1,24 @@ +SHORT Divide unit information + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 CYCLES_DIV_BUSY_ANY +PMC1:EDGEDETECT CYCLES_DIV_BUSY_ANY + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Number of divide ops PMC1:EDGEDETECT +Avg. divide unit usage duration PMC0/PMC1:EDGEDETECT + +LONG +Formulas: +Number of divide ops = CYCLES_DIV_BUSY_ANY:EDGEDETECT +Avg. divide unit usage duration = CYCLES_DIV_BUSY_ANY/CYCLES_DIV_BUSY_ANY:EDGEDETECT +- +This performance group measures the average latency of divide operations diff --git a/collectors/likwid/groups/silvermont/ENERGY.txt b/collectors/likwid/groups/silvermont/ENERGY.txt new file mode 100644 index 0000000..73939a3 --- /dev/null +++ b/collectors/likwid/groups/silvermont/ENERGY.txt @@ -0,0 +1,29 @@ +SHORT Power and Energy consumption + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +TMP0 TEMP_CORE +PWR0 PWR_PKG_ENERGY +PWR1 PWR_PP0_ENERGY + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Temperature [C] TMP0 +Energy [J] PWR0 +Power [W] PWR0/time +Energy PP0 [J] PWR1 +Power PP0 [W] PWR1/time + +LONG +Formulas: +Power = PWR_PKG_ENERGY / time +Power PP0 = PWR_PP0_ENERGY / time +- +Silvermont implements the new RAPL interface. This interface enables to +monitor the consumed energy on the package (socket) level. + diff --git a/collectors/likwid/groups/silvermont/ICACHE.txt b/collectors/likwid/groups/silvermont/ICACHE.txt new file mode 100644 index 0000000..5f11ad6 --- /dev/null +++ b/collectors/likwid/groups/silvermont/ICACHE.txt @@ -0,0 +1,25 @@ +SHORT Instruction cache miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 ICACHE_ACCESSES +PMC1 ICACHE_MISSES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L1I request rate PMC0/FIXC0 +L1I miss rate PMC1/FIXC0 +L1I miss ratio PMC1/PMC0 + +LONG +Formulas: +L1I request rate = ICACHE_ACCESSES / INSTR_RETIRED_ANY +L1I miss rate = ICACHE_MISSES / INSTR_RETIRED_ANY +L1I miss ratio = ICACHE_MISSES / ICACHE_ACCESSES +- +This group measures some L1 instruction cache metrics. diff --git a/collectors/likwid/groups/silvermont/L2CACHE.txt b/collectors/likwid/groups/silvermont/L2CACHE.txt new file mode 100644 index 0000000..32a1545 --- /dev/null +++ b/collectors/likwid/groups/silvermont/L2CACHE.txt @@ -0,0 +1,34 @@ +SHORT L2 cache miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 LONGEST_LAT_CACHE_REFERENCE +PMC1 LONGEST_LAT_CACHE_MISS + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L2 request rate PMC0/FIXC0 +L2 miss rate PMC1/FIXC0 +L2 miss ratio PMC1/PMC0 + +LONG +Formulas: +L2 request rate = LONGEST_LAT_CACHE_REFERENCE/INSTR_RETIRED_ANY +L2 miss rate = LONGEST_LAT_CACHE_MISS/INSTR_RETIRED_ANY +L2 miss ratio = LONGEST_LAT_CACHE_MISS/LONGEST_LAT_CACHE_REFERENCE +- +This group measures the locality of your data accesses with regard to the +L2 cache. L2 request rate tells you how data intensive your code is +or how many data accesses you have on average per instruction. +The L2 miss rate gives a measure how often it was necessary to get +cache lines from memory. And finally L2 miss ratio tells you how many of your +memory references required a cache line to be loaded from a higher level. +While the data cache miss rate might be given by your algorithm you should +try to get data cache miss ratio as low as possible by increasing your cache +reuse. + diff --git a/collectors/likwid/groups/silvermont/MEM.txt b/collectors/likwid/groups/silvermont/MEM.txt new file mode 100644 index 0000000..de78337 --- /dev/null +++ b/collectors/likwid/groups/silvermont/MEM.txt @@ -0,0 +1,37 @@ +SHORT Memory load bandwidth in MBytes/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 LONGEST_LAT_CACHE_MISS +PMC1 OFFCORE_RESPONSE_1_WB_ANY + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Memory read bandwidth [MBytes/s] 1.0E-06*(PMC0)*64.0/time +Memory read data volume [GBytes] 1.0E-09*(PMC0)*64.0 +Memory writeback bandwidth [MBytes/s] 1.0E-06*(PMC1)*64.0/time +Memory writeback data volume [GBytes] 1.0E-09*(PMC1)*64.0 +Memory bandwidth [MBytes/s] 1.0E-06*(PMC0+PMC1)*64.0/time +Memory data volume [GBytes] 1.0E-09*(PMC0+PMC1)*64.0 + +LONG +Formulas: +Memory read bandwidth [MBytes/s] = 1.0E-06*(LONGEST_LAT_CACHE_MISS)*64/time +Memory read data volume [GBytes] = 1.0E-09*(LONGEST_LAT_CACHE_MISS)*64 +Memory writeback bandwidth [MBytes/s] = 1.0E-06*(OFFCORE_RESPONSE_1_WB_ANY)*64/time +Memory writeback data volume [GBytes] = 1.0E-09*(OFFCORE_RESPONSE_1_WB_ANY)*64 +Memory bandwidth [MBytes/s] = 1.0E-06*(LONGEST_LAT_CACHE_MISS+OFFCORE_RESPONSE_1_WB_ANY)*64/time +Memory data volume [GBytes] = 1.0E-09*(LONGEST_LAT_CACHE_MISS+OFFCORE_RESPONSE_1_WB_ANY)*64 +- +Profiling group to measure L2 to MEM load cache bandwidth. The bandwidth is computed by the +number of cache line allocated in the L2 cache. Since there is no possibility to retrieve +the evicted cache lines, this group measures only the load cache bandwidth. The +writeback metrics count only modified cache lines that are written back to go to +exclusive state +The group also output totally load and writeback data volume transferred between memory and L2. + diff --git a/collectors/likwid/groups/silvermont/TLB_DATA.txt b/collectors/likwid/groups/silvermont/TLB_DATA.txt new file mode 100644 index 0000000..5f2617f --- /dev/null +++ b/collectors/likwid/groups/silvermont/TLB_DATA.txt @@ -0,0 +1,27 @@ +SHORT L2 data TLB miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 PAGE_WALKS_DTLB_COUNT +PMC1 PAGE_WALKS_DTLB_CYCLES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L1 DTLB misses PMC0 +L1 DTLB miss rate PMC0/FIXC0 +L1 DTLB miss duration [Cyc] PMC1/PMC0 + +LONG +Formulas: +L1 DTLB misses = PAGE_WALKS_DTLB_COUNT +L1 DTLB miss rate = PAGE_WALKS_DTLB_COUNT / INSTR_RETIRED_ANY +L1 DTLB miss duration [Cyc] = PAGE_WALKS_DTLB_CYCLES / PAGE_WALKS_DTLB_COUNT +- +The DTLB load and store miss rates gives a measure how often a TLB miss occurred +per instruction. The duration measures the time in cycles how long a walk did take. + diff --git a/collectors/likwid/groups/silvermont/TLB_INSTR.txt b/collectors/likwid/groups/silvermont/TLB_INSTR.txt new file mode 100644 index 0000000..f3dd3ec --- /dev/null +++ b/collectors/likwid/groups/silvermont/TLB_INSTR.txt @@ -0,0 +1,27 @@ +SHORT L1 Instruction TLB miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 PAGE_WALKS_ITLB_COUNT +PMC1 PAGE_WALKS_ITLB_CYCLES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L1 ITLB misses PMC0 +L1 ITLB miss rate PMC0/FIXC0 +L1 ITLB miss duration [Cyc] PMC1/PMC0 + + +LONG +Formulas: +L1 ITLB misses = PAGE_WALKS_ITLB_COUNT +L1 ITLB miss rate = PAGE_WALKS_ITLB_COUNT / INSTR_RETIRED_ANY +L1 ITLB miss duration [Cyc] = PAGE_WALKS_ITLB_CYCLES / PAGE_WALKS_ITLB_COUNT +- +The ITLB miss rates gives a measure how often a TLB miss occurred +per instruction. The duration measures the time in cycles how long a walk did take. diff --git a/collectors/likwid/groups/skylake/BRANCH.txt b/collectors/likwid/groups/skylake/BRANCH.txt new file mode 100644 index 0000000..b8d41b2 --- /dev/null +++ b/collectors/likwid/groups/skylake/BRANCH.txt @@ -0,0 +1,31 @@ +SHORT Branch prediction miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 BR_INST_RETIRED_ALL_BRANCHES +PMC1 BR_MISP_RETIRED_ALL_BRANCHES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Branch rate PMC0/FIXC0 +Branch misprediction rate PMC1/FIXC0 +Branch misprediction ratio PMC1/PMC0 +Instructions per branch FIXC0/PMC0 + +LONG +Formulas: +Branch rate = BR_INST_RETIRED_ALL_BRANCHES/INSTR_RETIRED_ANY +Branch misprediction rate = BR_MISP_RETIRED_ALL_BRANCHES/INSTR_RETIRED_ANY +Branch misprediction ratio = BR_MISP_RETIRED_ALL_BRANCHES/BR_INST_RETIRED_ALL_BRANCHES +Instructions per branch = INSTR_RETIRED_ANY/BR_INST_RETIRED_ALL_BRANCHES +- +The rates state how often on average a branch or a mispredicted branch occurred +per instruction retired in total. The branch misprediction ratio sets directly +into relation what ratio of all branch instruction where mispredicted. +Instructions per branch is 1/branch rate. + diff --git a/collectors/likwid/groups/skylake/CLOCK.txt b/collectors/likwid/groups/skylake/CLOCK.txt new file mode 100644 index 0000000..d682e3a --- /dev/null +++ b/collectors/likwid/groups/skylake/CLOCK.txt @@ -0,0 +1,30 @@ +SHORT Power and Energy consumption + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PWR0 PWR_PKG_ENERGY +PWR3 PWR_DRAM_ENERGY +UBOXFIX UNCORE_CLOCK + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +Uncore Clock [MHz] 1.E-06*UBOXFIX/time +CPI FIXC1/FIXC0 +Energy [J] PWR0 +Power [W] PWR0/time +Energy DRAM [J] PWR3 +Power DRAM [W] PWR3/time + +LONG +Formulas: +Power = PWR_PKG_ENERGY / time +Power DRAM = PWR_DRAM_ENERGY / time +Uncore Clock [MHz] = 1.E-06 * UNCORE_CLOCK / time +- +Skylake implements the RAPL interface. This interface enables to +monitor the consumed energy on the package (socket) and DRAM level. + diff --git a/collectors/likwid/groups/skylake/CYCLE_ACTIVITY.txt b/collectors/likwid/groups/skylake/CYCLE_ACTIVITY.txt new file mode 100644 index 0000000..c432a44 --- /dev/null +++ b/collectors/likwid/groups/skylake/CYCLE_ACTIVITY.txt @@ -0,0 +1,38 @@ +SHORT Cycle Activities + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 CYCLE_ACTIVITY_CYCLES_L2_PENDING +PMC1 CYCLE_ACTIVITY_CYCLES_LDM_PENDING +PMC2 CYCLE_ACTIVITY_CYCLES_L1D_PENDING +PMC3 CYCLE_ACTIVITY_CYCLES_NO_EXECUTE + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Cycles without execution [%] (PMC3/FIXC1)*100 +Cycles without execution due to L1D [%] (PMC2/FIXC1)*100 +Cycles without execution due to L2 [%] (PMC0/FIXC1)*100 +Cycles without execution due to memory loads [%] (PMC1/FIXC1)*100 + +LONG +Formulas: +Cycles without execution [%] = CYCLE_ACTIVITY_CYCLES_NO_EXECUTE/CPU_CLK_UNHALTED_CORE*100 +Cycles with stalls due to L1D [%] = CYCLE_ACTIVITY_CYCLES_L1D_PENDING/CPU_CLK_UNHALTED_CORE*100 +Cycles with stalls due to L2 [%] = CYCLE_ACTIVITY_CYCLES_L2_PENDING/CPU_CLK_UNHALTED_CORE*100 +Cycles without execution due to memory loads [%] = CYCLE_ACTIVITY_CYCLES_LDM_PENDING/CPU_CLK_UNHALTED_CORE*100 +-- +This performance group measures the cycles while waiting for data from the cache +and memory hierarchy. +CYCLE_ACTIVITY_CYCLES_NO_EXECUTE: Counts number of cycles nothing is executed on +any execution port. +CYCLE_ACTIVITY_CYCLES_L1D_PENDING: Cycles while L1 cache miss demand load is +outstanding. +CYCLE_ACTIVITY_CYCLES_L2_PENDING: Cycles while L2 cache miss demand load is +outstanding. +CYCLE_ACTIVITY_CYCLES_LDM_PENDING: Cycles while memory subsystem has an +outstanding load. diff --git a/collectors/likwid/groups/skylake/CYCLE_STALLS.txt b/collectors/likwid/groups/skylake/CYCLE_STALLS.txt new file mode 100644 index 0000000..795aeb9 --- /dev/null +++ b/collectors/likwid/groups/skylake/CYCLE_STALLS.txt @@ -0,0 +1,45 @@ +SHORT Cycle Activities (Stalls) + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 CYCLE_ACTIVITY_STALLS_L2_PENDING +PMC1 CYCLE_ACTIVITY_STALLS_LDM_PENDING +PMC2 CYCLE_ACTIVITY_STALLS_L1D_PENDING +PMC3 CYCLE_ACTIVITY_STALLS_TOTAL + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Total execution stalls PMC3 +Stalls caused by L1D misses [%] (PMC2/PMC3)*100 +Stalls caused by L2 misses [%] (PMC0/PMC3)*100 +Stalls caused by memory loads [%] (PMC1/PMC3)*100 +Execution stall rate [%] (PMC3/FIXC1)*100 +Stalls caused by L1D misses rate [%] (PMC2/FIXC1)*100 +Stalls caused by L2 misses rate [%] (PMC0/FIXC1)*100 +Stalls caused by memory loads rate [%] (PMC1/FIXC1)*100 + +LONG +Formulas: +Total execution stalls = CYCLE_ACTIVITY_STALLS_TOTAL +Stalls caused by L1D misses [%] = (CYCLE_ACTIVITY_STALLS_L1D_PENDING/CYCLE_ACTIVITY_STALLS_TOTAL)*100 +Stalls caused by L2 misses [%] = (CYCLE_ACTIVITY_STALLS_L2_PENDING/CYCLE_ACTIVITY_STALLS_TOTAL)*100 +Stalls caused by memory loads [%] = (CYCLE_ACTIVITY_STALLS_LDM_PENDING/CYCLE_ACTIVITY_STALLS_TOTAL)*100 +Execution stall rate [%] = (CYCLE_ACTIVITY_STALLS_TOTAL/CPU_CLK_UNHALTED_CORE)*100 +Stalls caused by L1D misses rate [%] = (CYCLE_ACTIVITY_STALLS_L1D_PENDING/CPU_CLK_UNHALTED_CORE)*100 +Stalls caused by L2 misses rate [%] = (CYCLE_ACTIVITY_STALLS_L2_PENDING/CPU_CLK_UNHALTED_CORE)*100 +Stalls caused by memory loads rate [%] = (CYCLE_ACTIVITY_STALLS_LDM_PENDING/CPU_CLK_UNHALTED_CORE)*100 +-- +This performance group measures the stalls caused by data traffic in the cache +hierarchy. +CYCLE_ACTIVITY_STALLS_TOTAL: Total execution stalls. +CYCLE_ACTIVITY_STALLS_L1D_PENDING: Execution stalls while L1 cache miss demand +load is outstanding. +CYCLE_ACTIVITY_STALLS_L2_PENDING: Execution stalls while L2 cache miss demand +load is outstanding. +CYCLE_ACTIVITY_STALLS_LDM_PENDING: Execution stalls while memory subsystem has +an outstanding load. diff --git a/collectors/likwid/groups/skylake/DATA.txt b/collectors/likwid/groups/skylake/DATA.txt new file mode 100644 index 0000000..4e6e938 --- /dev/null +++ b/collectors/likwid/groups/skylake/DATA.txt @@ -0,0 +1,22 @@ +SHORT Load to store ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 MEM_INST_RETIRED_ALL_LOADS +PMC1 MEM_INST_RETIRED_ALL_STORES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Load to store ratio PMC0/PMC1 + +LONG +Formulas: +Load to store ratio = MEM_INST_RETIRED_ALL_LOADS/MEM_INST_RETIRED_ALL_STORES +- +This is a metric to determine your load to store ratio. + diff --git a/collectors/likwid/groups/skylake/DIVIDE.txt b/collectors/likwid/groups/skylake/DIVIDE.txt new file mode 100644 index 0000000..40b4ab6 --- /dev/null +++ b/collectors/likwid/groups/skylake/DIVIDE.txt @@ -0,0 +1,24 @@ +SHORT Divide unit information + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 ARITH_DIVIDER_COUNT +PMC1 ARITH_DIVIDER_ACTIVE + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Number of divide ops PMC0 +Avg. divide unit usage duration PMC1/PMC0 + +LONG +Formulas: +Number of divide ops = ARITH_DIVIDER_COUNT +Avg. divide unit usage duration = ARITH_DIVIDER_ACTIVE/ARITH_DIVIDER_COUNT +- +This performance group measures the average latency of divide operations diff --git a/collectors/likwid/groups/skylake/ENERGY.txt b/collectors/likwid/groups/skylake/ENERGY.txt new file mode 100644 index 0000000..07dbda5 --- /dev/null +++ b/collectors/likwid/groups/skylake/ENERGY.txt @@ -0,0 +1,39 @@ +SHORT Power and Energy consumption + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +TMP0 TEMP_CORE +PWR0 PWR_PKG_ENERGY +PWR1 PWR_PP0_ENERGY +PWR2 PWR_PP1_ENERGY +PWR3 PWR_DRAM_ENERGY + + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Temperature [C] TMP0 +Energy [J] PWR0 +Power [W] PWR0/time +Energy PP0 [J] PWR1 +Power PP0 [W] PWR1/time +Energy PP1 [J] PWR2 +Power PP1 [W] PWR2/time +Energy DRAM [J] PWR3 +Power DRAM [W] PWR3/time + +LONG +Formulas: +Power = PWR_PKG_ENERGY / time +Power PP0 = PWR_PP0_ENERGY / time +Power PP1 = PWR_PP1_ENERGY / time +Power DRAM = PWR_DRAM_ENERGY / time +- +Skylake implements the RAPL interface. This interface enables to +monitor the consumed energy on the package (socket) and DRAM level. + diff --git a/collectors/likwid/groups/skylake/FALSE_SHARE.txt b/collectors/likwid/groups/skylake/FALSE_SHARE.txt new file mode 100644 index 0000000..65ff4d4 --- /dev/null +++ b/collectors/likwid/groups/skylake/FALSE_SHARE.txt @@ -0,0 +1,25 @@ +SHORT False sharing + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 MEM_LOAD_L3_HIT_RETIRED_XSNP_HITM +PMC2 MEM_INST_RETIRED_ALL + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Local LLC false sharing [MByte] 1.E-06*PMC0*64 +Local LLC false sharing rate PMC0/PMC2 + +LONG +Formulas: +Local LLC false sharing [MByte] = 1.E-06*MEM_LOAD_L3_HIT_RETIRED_XSNP_HITM*64 +Local LLC false sharing rate = MEM_LOAD_L3_HIT_RETIRED_XSNP_HITM/MEM_INST_RETIRED_ALL +- +False-sharing of cache lines can dramatically reduce the performance of an +application. This performance group measures the L3 traffic induced by false-sharing. +The false-sharing rate uses all memory loads as reference. diff --git a/collectors/likwid/groups/skylake/FLOPS_AVX.txt b/collectors/likwid/groups/skylake/FLOPS_AVX.txt new file mode 100644 index 0000000..ebde747 --- /dev/null +++ b/collectors/likwid/groups/skylake/FLOPS_AVX.txt @@ -0,0 +1,24 @@ +SHORT Packed AVX MFLOP/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE +PMC1 FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Packed SP [MFLOP/s] 1.0E-06*(PMC0*8.0)/time +Packed DP [MFLOP/s] 1.0E-06*(PMC1*4.0)/time + +LONG +Formulas: +Packed SP [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE*8)/runtime +Packed DP [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE*4)/runtime +- +Packed 32b AVX FLOPs rates. + diff --git a/collectors/likwid/groups/skylake/FLOPS_DP.txt b/collectors/likwid/groups/skylake/FLOPS_DP.txt new file mode 100644 index 0000000..ff7a833 --- /dev/null +++ b/collectors/likwid/groups/skylake/FLOPS_DP.txt @@ -0,0 +1,31 @@ +SHORT Double Precision MFLOP/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 FP_ARITH_INST_RETIRED_128B_PACKED_DOUBLE +PMC1 FP_ARITH_INST_RETIRED_SCALAR_DOUBLE +PMC2 FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +DP [MFLOP/s] 1.0E-06*(PMC0*2.0+PMC1+PMC2*4.0)/time +AVX DP [MFLOP/s] 1.0E-06*(PMC2*4.0)/time +Packed [MUOPS/s] 1.0E-06*(PMC0+PMC2)/time +Scalar [MUOPS/s] 1.0E-06*PMC1/time +Vectorization ratio 100*(PMC0+PMC2)/(PMC0+PMC1+PMC2) + +LONG +Formulas: +DP [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_128B_PACKED_DOUBLE*2+FP_ARITH_INST_RETIRED_SCALAR_DOUBLE+FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE*4)/runtime +AVX DP [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE*4)/runtime +Packed [MUOPS/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_128B_PACKED_DOUBLE+FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE)/runtime +Scalar [MUOPS/s] = 1.0E-06*FP_ARITH_INST_RETIRED_SCALAR_DOUBLE/runtime +Vectorization ratio = 100*(FP_ARITH_INST_RETIRED_128B_PACKED_DOUBLE+FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE)/(FP_ARITH_INST_RETIRED_SCALAR_DOUBLE+FP_ARITH_INST_RETIRED_128B_PACKED_DOUBLE+FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE) +- +SSE scalar and packed double precision FLOP rates. + diff --git a/collectors/likwid/groups/skylake/FLOPS_SP.txt b/collectors/likwid/groups/skylake/FLOPS_SP.txt new file mode 100644 index 0000000..3a7d56b --- /dev/null +++ b/collectors/likwid/groups/skylake/FLOPS_SP.txt @@ -0,0 +1,31 @@ +SHORT Single Precision MFLOP/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 FP_ARITH_INST_RETIRED_128B_PACKED_SINGLE +PMC1 FP_ARITH_INST_RETIRED_SCALAR_SINGLE +PMC2 FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +SP [MFLOP/s] 1.0E-06*(PMC0*4.0+PMC1+PMC2*8.0)/time +AVX SP [MFLOP/s] 1.0E-06*(PMC2*8.0)/time +Packed [MUOPS/s] 1.0E-06*(PMC0+PMC2)/time +Scalar [MUOPS/s] 1.0E-06*PMC1/time +Vectorization ratio 100*(PMC0+PMC2)/(PMC0+PMC1+PMC2) + +LONG +Formulas: +SP [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_128B_PACKED_SINGLE*4+FP_ARITH_INST_RETIRED_SCALAR_SINGLE+FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE*8)/runtime +AVX SP [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE*8)/runtime +Packed [MUOPS/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_128B_PACKED_SINGLE+FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE)/runtime +Scalar [MUOPS/s] = 1.0E-06*FP_ARITH_INST_RETIRED_SCALAR_SINGLE/runtime +Vectorization ratio [%] = 100*(FP_ARITH_INST_RETIRED_128B_PACKED_SINGLE+FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE)/(FP_ARITH_INST_RETIRED_SCALAR_SINGLE+FP_ARITH_INST_RETIRED_128B_PACKED_SINGLE+FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE) +- +SSE scalar and packed single precision FLOP rates. + diff --git a/collectors/likwid/groups/skylake/ICACHE.txt b/collectors/likwid/groups/skylake/ICACHE.txt new file mode 100644 index 0000000..aab7dac --- /dev/null +++ b/collectors/likwid/groups/skylake/ICACHE.txt @@ -0,0 +1,30 @@ +SHORT Instruction cache miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 ICACHE_64B_IFTAG_ALL +PMC1 ICACHE_64B_IFTAG_MISS +PMC2 ICACHE_64B_IFTAG_STALL + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L1I request rate PMC0/FIXC0 +L1I miss rate PMC1/FIXC0 +L1I miss ratio PMC1/PMC0 +L1I stalls PMC2 +L1I stall rate PMC2/FIXC0 + +LONG +Formulas: +L1I request rate = ICACHE_ACCESSES / INSTR_RETIRED_ANY +L1I miss rate = ICACHE_MISSES / INSTR_RETIRED_ANY +L1I miss ratio = ICACHE_MISSES / ICACHE_ACCESSES +L1I stalls = ICACHE_IFETCH_STALL +L1I stall rate = ICACHE_IFETCH_STALL / INSTR_RETIRED_ANY +- +This group measures some L1 instruction cache metrics. diff --git a/collectors/likwid/groups/skylake/L2.txt b/collectors/likwid/groups/skylake/L2.txt new file mode 100644 index 0000000..1a92a95 --- /dev/null +++ b/collectors/likwid/groups/skylake/L2.txt @@ -0,0 +1,38 @@ +SHORT L2 cache bandwidth in MBytes/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 L1D_REPLACEMENT +PMC1 L1D_M_EVICT +PMC2 ICACHE_64B_IFTAG_MISS + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L2D load bandwidth [MBytes/s] 1.0E-06*PMC0*64.0/time +L2D load data volume [GBytes] 1.0E-09*PMC0*64.0 +L2D evict bandwidth [MBytes/s] 1.0E-06*PMC1*64.0/time +L2D evict data volume [GBytes] 1.0E-09*PMC1*64.0 +L2 bandwidth [MBytes/s] 1.0E-06*(PMC0+PMC1+PMC2)*64.0/time +L2 data volume [GBytes] 1.0E-09*(PMC0+PMC1+PMC2)*64.0 + +LONG +Formulas: +L2D load bandwidth [MBytes/s] = 1.0E-06*L1D_REPLACEMENT*64.0/time +L2D load data volume [GBytes] = 1.0E-09*L1D_REPLACEMENT*64.0 +L2D evict bandwidth [MBytes/s] = 1.0E-06*L1D_M_EVICT*64.0/time +L2D evict data volume [GBytes] = 1.0E-09*L1D_M_EVICT*64.0 +L2 bandwidth [MBytes/s] = 1.0E-06*(L1D_REPLACEMENT+L1D_M_EVICT+ICACHE_64B_IFTAG_MISS)*64/time +L2 data volume [GBytes] = 1.0E-09*(L1D_REPLACEMENT+L1D_M_EVICT+ICACHE_64B_IFTAG_MISS)*64 +- +Profiling group to measure L2 cache bandwidth. The bandwidth is computed by the +number of cache line allocated in the L1 and the number of modified cache lines +evicted from the L1. The group also output total data volume transferred between +L2 and L1. Note that this bandwidth also includes data transfers due to a write +allocate load on a store miss in L1 and traffic caused by misses in the +L1 instruction cache. + diff --git a/collectors/likwid/groups/skylake/L2CACHE.txt b/collectors/likwid/groups/skylake/L2CACHE.txt new file mode 100644 index 0000000..fbc3745 --- /dev/null +++ b/collectors/likwid/groups/skylake/L2CACHE.txt @@ -0,0 +1,34 @@ +SHORT L2 cache miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 L2_TRANS_ALL_REQUESTS +PMC1 L2_RQSTS_MISS + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L2 request rate PMC0/FIXC0 +L2 miss rate PMC1/FIXC0 +L2 miss ratio PMC1/PMC0 + +LONG +Formulas: +L2 request rate = L2_TRANS_ALL_REQUESTS/INSTR_RETIRED_ANY +L2 miss rate = L2_RQSTS_MISS/INSTR_RETIRED_ANY +L2 miss ratio = L2_RQSTS_MISS/L2_TRANS_ALL_REQUESTS +- +This group measures the locality of your data accesses with regard to the +L2 cache. L2 request rate tells you how data intensive your code is +or how many data accesses you have on average per instruction. +The L2 miss rate gives a measure how often it was necessary to get +cache lines from memory. And finally L2 miss ratio tells you how many of your +memory references required a cache line to be loaded from a higher level. +While the data cache miss rate might be given by your algorithm you should +try to get data cache miss ratio as low as possible by increasing your cache reuse. + + diff --git a/collectors/likwid/groups/skylake/L3.txt b/collectors/likwid/groups/skylake/L3.txt new file mode 100644 index 0000000..f63a918 --- /dev/null +++ b/collectors/likwid/groups/skylake/L3.txt @@ -0,0 +1,36 @@ +SHORT L3 cache bandwidth in MBytes/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 L2_LINES_IN_ALL +PMC1 L2_TRANS_L2_WB + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L3 load bandwidth [MBytes/s] 1.0E-06*PMC0*64.0/time +L3 load data volume [GBytes] 1.0E-09*PMC0*64.0 +L3 evict bandwidth [MBytes/s] 1.0E-06*PMC1*64.0/time +L3 evict data volume [GBytes] 1.0E-09*PMC1*64.0 +L3 bandwidth [MBytes/s] 1.0E-06*(PMC0+PMC1)*64.0/time +L3 data volume [GBytes] 1.0E-09*(PMC0+PMC1)*64.0 + +LONG +Formulas: +L3 load bandwidth [MBytes/s] = 1.0E-06*L2_LINES_IN_ALL*64.0/time +L3 load data volume [GBytes] = 1.0E-09*L2_LINES_IN_ALL*64.0 +L3 evict bandwidth [MBytes/s] = 1.0E-06*L2_TRANS_L2_WB*64.0/time +L3 evict data volume [GBytes] = 1.0E-09*L2_TRANS_L2_WB*64.0 +L3 bandwidth [MBytes/s] = 1.0E-06*(L2_LINES_IN_ALL+L2_TRANS_L2_WB)*64/time +L3 data volume [GBytes] = 1.0E-09*(L2_LINES_IN_ALL+L2_TRANS_L2_WB)*64 +- +Profiling group to measure L3 cache bandwidth. The bandwidth is computed by the +number of cache line allocated in the L2 and the number of modified cache lines +evicted from the L2. This group also output data volume transferred between the +L3 and measured cores L2 caches. Note that this bandwidth also includes data +transfers due to a write allocate load on a store miss in L2. + diff --git a/collectors/likwid/groups/skylake/L3CACHE.txt b/collectors/likwid/groups/skylake/L3CACHE.txt new file mode 100644 index 0000000..94953ef --- /dev/null +++ b/collectors/likwid/groups/skylake/L3CACHE.txt @@ -0,0 +1,35 @@ +SHORT L3 cache miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 MEM_LOAD_RETIRED_L3_HIT +PMC1 MEM_LOAD_RETIRED_L3_MISS +PMC2 UOPS_RETIRED_ALL + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L3 request rate (PMC0+PMC1)/PMC2 +L3 miss rate PMC1/PMC2 +L3 miss ratio PMC1/(PMC0+PMC1) + +LONG +Formulas: +L3 request rate = (MEM_LOAD_RETIRED_L3_HIT+MEM_LOAD_RETIRED_L3_MISS)/UOPS_RETIRED_ALL +L3 miss rate = MEM_LOAD_RETIRED_L3_MISS/UOPS_RETIRED_ALL +L3 miss ratio = MEM_LOAD_RETIRED_L3_MISS/(MEM_LOAD_RETIRED_L3_HIT+MEM_LOAD_RETIRED_L3_MISS) +- +This group measures the locality of your data accesses with regard to the +L3 cache. L3 request rate tells you how data intensive your code is +or how many data accesses you have on average per instruction. +The L3 miss rate gives a measure how often it was necessary to get +cache lines from memory. And finally L3 miss ratio tells you how many of your +memory references required a cache line to be loaded from a higher level. +While the data cache miss rate might be given by your algorithm you should +try to get data cache miss ratio as low as possible by increasing your cache reuse. + + diff --git a/collectors/likwid/groups/skylake/MEM.txt b/collectors/likwid/groups/skylake/MEM.txt new file mode 100644 index 0000000..3a12df7 --- /dev/null +++ b/collectors/likwid/groups/skylake/MEM.txt @@ -0,0 +1,36 @@ +SHORT L3 cache bandwidth in MBytes/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +MBOX0C1 DRAM_READS +MBOX0C2 DRAM_WRITES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Memory load bandwidth [MBytes/s] 1.0E-06*MBOX0C1*64.0/time +Memory load data volume [GBytes] 1.0E-09*MBOX0C1*64.0 +Memory evict bandwidth [MBytes/s] 1.0E-06*MBOX0C2*64.0/time +Memory evict data volume [GBytes] 1.0E-09*MBOX0C2*64.0 +Memory bandwidth [MBytes/s] 1.0E-06*(MBOX0C1+MBOX0C2)*64.0/time +Memory data volume [GBytes] 1.0E-09*(MBOX0C1+MBOX0C2)*64.0 + +LONG +Formulas: +L3 load bandwidth [MBytes/s] = 1.0E-06*L2_LINES_IN_ALL*64.0/time +L3 load data volume [GBytes] = 1.0E-09*L2_LINES_IN_ALL*64.0 +L3 evict bandwidth [MBytes/s] = 1.0E-06*L2_TRANS_L2_WB*64.0/time +L3 evict data volume [GBytes] = 1.0E-09*L2_TRANS_L2_WB*64.0 +L3 bandwidth [MBytes/s] = 1.0E-06*(L2_LINES_IN_ALL+L2_TRANS_L2_WB)*64/time +L3 data volume [GBytes] = 1.0E-09*(L2_LINES_IN_ALL+L2_TRANS_L2_WB)*64 +- +Profiling group to measure L3 cache bandwidth. The bandwidth is computed by the +number of cache line allocated in the L2 and the number of modified cache lines +evicted from the L2. This group also output data volume transferred between the +L3 and measured cores L2 caches. Note that this bandwidth also includes data +transfers due to a write allocate load on a store miss in L2. + diff --git a/collectors/likwid/groups/skylake/MEM_DP.txt b/collectors/likwid/groups/skylake/MEM_DP.txt new file mode 100644 index 0000000..14a359a --- /dev/null +++ b/collectors/likwid/groups/skylake/MEM_DP.txt @@ -0,0 +1,59 @@ +SHORT Overview of arithmetic and main memory performance + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PWR0 PWR_PKG_ENERGY +PWR3 PWR_DRAM_ENERGY +PMC0 FP_ARITH_INST_RETIRED_128B_PACKED_DOUBLE +PMC1 FP_ARITH_INST_RETIRED_SCALAR_DOUBLE +PMC2 FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE +MBOX0C1 DRAM_READS +MBOX0C2 DRAM_WRITES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Energy [J] PWR0 +Power [W] PWR0/time +Energy DRAM [J] PWR3 +Power DRAM [W] PWR3/time +DP [MFLOP/s] 1.0E-06*(PMC0*2.0+PMC1+PMC2*4.0)/time +AVX DP [MFLOP/s] 1.0E-06*(PMC2*4.0)/time +Packed [MUOPS/s] 1.0E-06*(PMC0+PMC2)/time +Scalar [MUOPS/s] 1.0E-06*PMC1/time +Memory load bandwidth [MBytes/s] 1.0E-06*MBOX0C1*64.0/time +Memory load data volume [GBytes] 1.0E-09*MBOX0C1*64.0 +Memory evict bandwidth [MBytes/s] 1.0E-06*MBOX0C2*64.0/time +Memory evict data volume [GBytes] 1.0E-09*MBOX0C2*64.0 +Memory bandwidth [MBytes/s] 1.0E-06*(MBOX0C1+MBOX0C2)*64.0/time +Memory data volume [GBytes] 1.0E-09*(MBOX0C1+MBOX0C2)*64.0 +Operational intensity (PMC0*2.0+PMC1+PMC2*4.0)/((MBOX0C1+MBOX0C2)*64.0) + +LONG +Formulas: +Power [W] = PWR_PKG_ENERGY/runtime +Power DRAM [W] = PWR_DRAM_ENERGY/runtime +DP [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_128B_PACKED_DOUBLE*2+FP_ARITH_INST_RETIRED_SCALAR_DOUBLE+FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE*4)/runtime +AVX DP [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE*4)/runtime +Packed [MUOPS/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_128B_PACKED_DOUBLE+FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE)/runtime +Scalar [MUOPS/s] = 1.0E-06*FP_ARITH_INST_RETIRED_SCALAR_DOUBLE/runtime +Memory read bandwidth [MBytes/s] = 1.0E-06*DRAM_READS*64.0/runtime +Memory read data volume [GBytes] = 1.0E-09*DRAM_READS*64.0 +Memory write bandwidth [MBytes/s] = 1.0E-06*DRAM_WRITES*64.0/runtime +Memory write data volume [GBytes] = 1.0E-09*DRAM_WRITES*64.0 +Memory bandwidth [MBytes/s] = 1.0E-06*(DRAM_READS+DRAM_WRITES)*64.0/runtime +Memory data volume [GBytes] = 1.0E-09*(DRAM_READS+DRAM_WRITES)*64.0 +Operational intensity = (FP_ARITH_INST_RETIRED_128B_PACKED_DOUBLE*2+FP_ARITH_INST_RETIRED_SCALAR_DOUBLE+FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE*4)/(DRAM_READS+DRAM_WRITES)*64.0) +-- +Profiling group to measure memory bandwidth drawn by all cores of a socket. +Since this group is based on Uncore events it is only possible to measure on +a per socket base. Also outputs total data volume transferred from main memory. +SSE scalar and packed double precision FLOP rates. Also reports on packed AVX +32b instructions. +The operational intensity is calculated using the FP values of the cores and the +memory data volume of the whole socket. The actual operational intensity for +multiple CPUs can be found in the statistics table in the Sum column. diff --git a/collectors/likwid/groups/skylake/MEM_SP.txt b/collectors/likwid/groups/skylake/MEM_SP.txt new file mode 100644 index 0000000..0b47052 --- /dev/null +++ b/collectors/likwid/groups/skylake/MEM_SP.txt @@ -0,0 +1,59 @@ +SHORT L3 cache bandwidth in MBytes/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PWR0 PWR_PKG_ENERGY +PWR3 PWR_DRAM_ENERGY +PMC0 FP_ARITH_INST_RETIRED_128B_PACKED_SINGLE +PMC1 FP_ARITH_INST_RETIRED_SCALAR_SINGLE +PMC2 FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE +MBOX0C1 DRAM_READS +MBOX0C2 DRAM_WRITES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Energy [J] PWR0 +Power [W] PWR0/time +Energy DRAM [J] PWR3 +Power DRAM [W] PWR3/time +SP [MFLOP/s] 1.0E-06*(PMC0*4.0+PMC1+PMC2*8.0)/time +AVX SP [MFLOP/s] 1.0E-06*(PMC2*8.0)/time +Packed [MUOPS/s] 1.0E-06*(PMC0+PMC2)/time +Scalar [MUOPS/s] 1.0E-06*PMC1/time +Memory load bandwidth [MBytes/s] 1.0E-06*MBOX0C1*64.0/time +Memory load data volume [GBytes] 1.0E-09*MBOX0C1*64.0 +Memory evict bandwidth [MBytes/s] 1.0E-06*MBOX0C2*64.0/time +Memory evict data volume [GBytes] 1.0E-09*MBOX0C2*64.0 +Memory bandwidth [MBytes/s] 1.0E-06*(MBOX0C1+MBOX0C2)*64.0/time +Memory data volume [GBytes] 1.0E-09*(MBOX0C1+MBOX0C2)*64.0 +Operational intensity (PMC0*4.0+PMC1+PMC2*8.0)/((MBOX0C1+MBOX0C2)*64.0) + +LONG +Formulas: +Power [W] = PWR_PKG_ENERGY/runtime +Power DRAM [W] = PWR_DRAM_ENERGY/runtime +DP [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_128B_PACKED_DOUBLE*4+FP_ARITH_INST_RETIRED_SCALAR_DOUBLE+FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE*8)/runtime +AVX DP [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE*8)/runtime +Packed [MUOPS/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_128B_PACKED_DOUBLE+FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE)/runtime +Scalar [MUOPS/s] = 1.0E-06*FP_ARITH_INST_RETIRED_SCALAR_DOUBLE/runtime +Memory read bandwidth [MBytes/s] = 1.0E-06*DRAM_READS*64.0/runtime +Memory read data volume [GBytes] = 1.0E-09*DRAM_READS*64.0 +Memory write bandwidth [MBytes/s] = 1.0E-06*DRAM_WRITES*64.0/runtime +Memory write data volume [GBytes] = 1.0E-09*DRAM_WRITES*64.0 +Memory bandwidth [MBytes/s] = 1.0E-06*(DRAM_READS+DRAM_WRITES)*64.0/runtime +Memory data volume [GBytes] = 1.0E-09*(DRAM_READS+DRAM_WRITES)*64.0 +Operational intensity = (FP_ARITH_INST_RETIRED_128B_PACKED_DOUBLE*4+FP_ARITH_INST_RETIRED_SCALAR_DOUBLE+FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE*8)/(DRAM_READS+DRAM_WRITES)*64.0) +- +Profiling group to measure memory bandwidth drawn by all cores of a socket. +Since this group is based on Uncore events it is only possible to measure on +a per socket base. Also outputs total data volume transferred from main memory. +SSE scalar and packed single precision FLOP rates. Also reports on packed AVX +32b instructions. +The operational intensity is calculated using the FP values of the cores and the +memory data volume of the whole socket. The actual operational intensity for +multiple CPUs can be found in the statistics table in the Sum column. diff --git a/collectors/likwid/groups/skylake/PORT_USAGE.txt b/collectors/likwid/groups/skylake/PORT_USAGE.txt new file mode 100644 index 0000000..eca8f2a --- /dev/null +++ b/collectors/likwid/groups/skylake/PORT_USAGE.txt @@ -0,0 +1,46 @@ +SHORT Execution port utilization + +REQUIRE_NOHT + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 UOPS_DISPATCHED_PORT_PORT_0 +PMC1 UOPS_DISPATCHED_PORT_PORT_1 +PMC2 UOPS_DISPATCHED_PORT_PORT_2 +PMC3 UOPS_DISPATCHED_PORT_PORT_3 +PMC4 UOPS_DISPATCHED_PORT_PORT_4 +PMC5 UOPS_DISPATCHED_PORT_PORT_5 +PMC6 UOPS_DISPATCHED_PORT_PORT_6 +PMC7 UOPS_DISPATCHED_PORT_PORT_7 + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Port0 usage ratio PMC0/(PMC0+PMC1+PMC2+PMC3+PMC4+PMC5+PMC6+PMC7) +Port1 usage ratio PMC1/(PMC0+PMC1+PMC2+PMC3+PMC4+PMC5+PMC6+PMC7) +Port2 usage ratio PMC2/(PMC0+PMC1+PMC2+PMC3+PMC4+PMC5+PMC6+PMC7) +Port3 usage ratio PMC3/(PMC0+PMC1+PMC2+PMC3+PMC4+PMC5+PMC6+PMC7) +Port4 usage ratio PMC4/(PMC0+PMC1+PMC2+PMC3+PMC4+PMC5+PMC6+PMC7) +Port5 usage ratio PMC5/(PMC0+PMC1+PMC2+PMC3+PMC4+PMC5+PMC6+PMC7) +Port6 usage ratio PMC6/(PMC0+PMC1+PMC2+PMC3+PMC4+PMC5+PMC6+PMC7) +Port7 usage ratio PMC7/(PMC0+PMC1+PMC2+PMC3+PMC4+PMC5+PMC6+PMC7) + +LONG +Formulas: +Port0 usage ratio = UOPS_DISPATCHED_PORT_PORT_0/SUM(UOPS_DISPATCHED_PORT_PORT_*) +Port1 usage ratio = UOPS_DISPATCHED_PORT_PORT_1/SUM(UOPS_DISPATCHED_PORT_PORT_*) +Port2 usage ratio = UOPS_DISPATCHED_PORT_PORT_2/SUM(UOPS_DISPATCHED_PORT_PORT_*) +Port3 usage ratio = UOPS_DISPATCHED_PORT_PORT_3/SUM(UOPS_DISPATCHED_PORT_PORT_*) +Port4 usage ratio = UOPS_DISPATCHED_PORT_PORT_4/SUM(UOPS_DISPATCHED_PORT_PORT_*) +Port5 usage ratio = UOPS_DISPATCHED_PORT_PORT_5/SUM(UOPS_DISPATCHED_PORT_PORT_*) +Port6 usage ratio = UOPS_DISPATCHED_PORT_PORT_6/SUM(UOPS_DISPATCHED_PORT_PORT_*) +Port7 usage ratio = UOPS_DISPATCHED_PORT_PORT_7/SUM(UOPS_DISPATCHED_PORT_PORT_*) +- +This group measures the execution port utilization in a CPU core. The group can +only be measured when HyperThreading is disabled because only then each CPU core +can program eight counters. diff --git a/collectors/likwid/groups/skylake/RECOVERY.txt b/collectors/likwid/groups/skylake/RECOVERY.txt new file mode 100644 index 0000000..7928ee4 --- /dev/null +++ b/collectors/likwid/groups/skylake/RECOVERY.txt @@ -0,0 +1,22 @@ +SHORT Recovery duration + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 INT_MISC_RECOVERY_CYCLES +PMC1 INT_MISC_RECOVERY_COUNT + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Avg. recovery duration PMC0/PMC1 + +LONG +Formulas: +Avg. recovery duration = INT_MISC_RECOVERY_CYCLES/INT_MISC_RECOVERY_COUNT +- +This group measures the duration of recoveries after SSE exception, memory +disambiguation, etc... diff --git a/collectors/likwid/groups/skylake/TLB_DATA.txt b/collectors/likwid/groups/skylake/TLB_DATA.txt new file mode 100644 index 0000000..10ee5e1 --- /dev/null +++ b/collectors/likwid/groups/skylake/TLB_DATA.txt @@ -0,0 +1,35 @@ +SHORT L2 data TLB miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 DTLB_LOAD_MISSES_CAUSES_A_WALK +PMC1 DTLB_STORE_MISSES_CAUSES_A_WALK +PMC2 DTLB_LOAD_MISSES_WALK_ACTIVE +PMC3 DTLB_STORE_MISSES_WALK_ACTIVE + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L1 DTLB load misses PMC0 +L1 DTLB load miss rate PMC0/FIXC0 +L1 DTLB load miss duration [Cyc] PMC2/PMC0 +L1 DTLB store misses PMC1 +L1 DTLB store miss rate PMC1/FIXC0 +L1 DTLB store miss duration [Cyc] PMC3/PMC1 + +LONG +Formulas: +L1 DTLB load misses = DTLB_LOAD_MISSES_CAUSES_A_WALK +L1 DTLB load miss rate = DTLB_LOAD_MISSES_CAUSES_A_WALK / INSTR_RETIRED_ANY +L1 DTLB load miss duration [Cyc] = DTLB_LOAD_MISSES_WALK_ACTIVE / DTLB_LOAD_MISSES_CAUSES_A_WALK +L1 DTLB store misses = DTLB_STORE_MISSES_CAUSES_A_WALK +L1 DTLB store miss rate = DTLB_STORE_MISSES_CAUSES_A_WALK / INSTR_RETIRED_ANY +L1 DTLB store miss duration [Cyc] = DTLB_STORE_MISSES_WALK_ACTIVE / DTLB_STORE_MISSES_CAUSES_A_WALK +- +The DTLB load and store miss rates gives a measure how often a TLB miss occurred +per instruction. The duration measures the time in cycles how long a walk did take. + diff --git a/collectors/likwid/groups/skylake/TLB_INSTR.txt b/collectors/likwid/groups/skylake/TLB_INSTR.txt new file mode 100644 index 0000000..9bc65a7 --- /dev/null +++ b/collectors/likwid/groups/skylake/TLB_INSTR.txt @@ -0,0 +1,28 @@ +SHORT L1 Instruction TLB miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 ITLB_MISSES_CAUSES_A_WALK +PMC1 ITLB_MISSES_WALK_ACTIVE + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L1 ITLB misses PMC0 +L1 ITLB miss rate PMC0/FIXC0 +L1 ITLB miss duration [Cyc] PMC1/PMC0 + + +LONG +Formulas: +L1 ITLB misses = ITLB_MISSES_CAUSES_A_WALK +L1 ITLB miss rate = ITLB_MISSES_CAUSES_A_WALK / INSTR_RETIRED_ANY +L1 ITLB miss duration [Cyc] = ITLB_MISSES_WALK_ACTIVE / ITLB_MISSES_CAUSES_A_WALK +- +The ITLB miss rates gives a measure how often a TLB miss occurred +per instruction. The duration measures the time in cycles how long a walk did take. + diff --git a/collectors/likwid/groups/skylake/TMA.txt b/collectors/likwid/groups/skylake/TMA.txt new file mode 100644 index 0000000..afb4126 --- /dev/null +++ b/collectors/likwid/groups/skylake/TMA.txt @@ -0,0 +1,48 @@ +SHORT Top down cycle allocation + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 UOPS_ISSUED_ANY +PMC1 UOPS_RETIRED_RETIRE_SLOTS +PMC2 IDQ_UOPS_NOT_DELIVERED_CORE +PMC3 INT_MISC_RECOVERY_CYCLES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +IPC FIXC0/FIXC1 +Total Slots 4*FIXC1 +Slots Retired PMC1 +Fetch Bubbles PMC2 +Recovery Bubbles 4*PMC3 +Front End [%] PMC2/(4*FIXC1)*100 +Speculation [%] (PMC0-PMC1+(4*PMC3))/(4*FIXC1)*100 +Retiring [%] PMC1/(4*FIXC1)*100 +Back End [%] (1-((PMC2+PMC0+(4*PMC3))/(4*FIXC1)))*100 + +LONG +Formulas: +Total Slots = 4*CPU_CLK_UNHALTED_CORE +Slots Retired = UOPS_RETIRED_RETIRE_SLOTS +Fetch Bubbles = IDQ_UOPS_NOT_DELIVERED_CORE +Recovery Bubbles = 4*INT_MISC_RECOVERY_CYCLES +Front End [%] = IDQ_UOPS_NOT_DELIVERED_CORE/(4*CPU_CLK_UNHALTED_CORE)*100 +Speculation [%] = (UOPS_ISSUED_ANY-UOPS_RETIRED_RETIRE_SLOTS+(4*INT_MISC_RECOVERY_CYCLES))/(4*CPU_CLK_UNHALTED_CORE)*100 +Retiring [%] = UOPS_RETIRED_RETIRE_SLOTS/(4*CPU_CLK_UNHALTED_CORE)*100 +Back End [%] = (1-((IDQ_UOPS_NOT_DELIVERED_CORE+UOPS_ISSUED_ANY+(4*INT_MISC_RECOVERY_CYCLES))/(4*CPU_CLK_UNHALTED_CORE)))*100 +-- +This performance group measures cycles to determine percentage of time spent in +front end, back end, retiring and speculation. These metrics are published and +verified by Intel. Further information: +Webpage describing Top-Down Method and its usage in Intel vTune: +https://software.intel.com/en-us/vtune-amplifier-help-tuning-applications-using-a-top-down-microarchitecture-analysis-method +Paper by Yasin Ahmad: +https://sites.google.com/site/analysismethods/yasin-pubs/TopDown-Yasin-ISPASS14.pdf?attredirects=0 +Slides by Yasin Ahmad: +http://www.cs.technion.ac.il/~erangi/TMA_using_Linux_perf__Ahmad_Yasin.pdf +The performance group was originally published here: +http://perf.mvermeulen.com/2018/04/14/top-down-performance-counter-analysis-part-1-likwid/ diff --git a/collectors/likwid/groups/skylake/UOPS.txt b/collectors/likwid/groups/skylake/UOPS.txt new file mode 100644 index 0000000..c0a86f2 --- /dev/null +++ b/collectors/likwid/groups/skylake/UOPS.txt @@ -0,0 +1,29 @@ +SHORT UOPs execution info + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 UOPS_ISSUED_ANY +PMC1 UOPS_EXECUTED_THREAD +PMC2 UOPS_RETIRED_ALL + + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Issued UOPs PMC0 +Executed UOPs PMC1 +Retired UOPs PMC2 + +LONG +Formulas: +Issued UOPs = UOPS_ISSUED_ANY +Executed UOPs = UOPS_EXECUTED_THREAD +Retired UOPs = UOPS_RETIRED_ALL +- +This group returns information about the instruction pipeline. It measures the +issued, executed and retired uOPs. diff --git a/collectors/likwid/groups/skylake/UOPS_EXEC.txt b/collectors/likwid/groups/skylake/UOPS_EXEC.txt new file mode 100644 index 0000000..7042df7 --- /dev/null +++ b/collectors/likwid/groups/skylake/UOPS_EXEC.txt @@ -0,0 +1,31 @@ +SHORT UOPs execution + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 UOPS_EXECUTED_USED_CYCLES +PMC1 UOPS_EXECUTED_STALL_CYCLES +PMC2 CPU_CLOCK_UNHALTED_TOTAL_CYCLES +PMC3:EDGEDETECT UOPS_EXECUTED_STALL_CYCLES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Used cycles ratio [%] 100*PMC0/PMC2 +Unused cycles ratio [%] 100*PMC1/PMC2 +Avg stall duration [cycles] PMC1/PMC3:EDGEDETECT + + +LONG +Formulas: +Used cycles ratio [%] = 100*UOPS_EXECUTED_USED_CYCLES/CPU_CLK_UNHALTED_CORE +Unused cycles ratio [%] = 100*UOPS_EXECUTED_STALL_CYCLES/CPU_CLK_UNHALTED_CORE +Avg stall duration [cycles] = UOPS_EXECUTED_STALL_CYCLES/UOPS_EXECUTED_STALL_CYCLES:EDGEDETECT +- +This performance group returns the ratios of used and unused cycles regarding +the execution stage in the pipeline. Used cycles are all cycles where uOPs are +executed while unused cycles refer to pipeline stalls. Moreover, the group +calculates the average stall duration in cycles. diff --git a/collectors/likwid/groups/skylake/UOPS_ISSUE.txt b/collectors/likwid/groups/skylake/UOPS_ISSUE.txt new file mode 100644 index 0000000..9aac923 --- /dev/null +++ b/collectors/likwid/groups/skylake/UOPS_ISSUE.txt @@ -0,0 +1,31 @@ +SHORT UOPs issueing + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 UOPS_ISSUED_USED_CYCLES +PMC1 UOPS_ISSUED_STALL_CYCLES +PMC2 CPU_CLOCK_UNHALTED_TOTAL_CYCLES +PMC3:EDGEDETECT UOPS_ISSUED_STALL_CYCLES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Used cycles ratio [%] 100*PMC0/PMC2 +Unused cycles ratio [%] 100*PMC1/PMC2 +Avg stall duration [cycles] PMC1/PMC3:EDGEDETECT + + +LONG +Formulas: +Used cycles ratio [%] = 100*UOPS_ISSUED_USED_CYCLES/CPU_CLK_UNHALTED_CORE +Unused cycles ratio [%] = 100*UOPS_ISSUED_STALL_CYCLES/CPU_CLK_UNHALTED_CORE +Avg stall duration [cycles] = UOPS_ISSUED_STALL_CYCLES/UOPS_ISSUED_STALL_CYCLES:EDGEDETECT +- +This performance group returns the ratios of used and unused cycles regarding +the issue stage in the pipeline. Used cycles are all cycles where uOPs are +issued while unused cycles refer to pipeline stalls. Moreover, the group +calculates the average stall duration in cycles. diff --git a/collectors/likwid/groups/skylake/UOPS_RETIRE.txt b/collectors/likwid/groups/skylake/UOPS_RETIRE.txt new file mode 100644 index 0000000..0f37585 --- /dev/null +++ b/collectors/likwid/groups/skylake/UOPS_RETIRE.txt @@ -0,0 +1,31 @@ +SHORT UOPs retirement + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 UOPS_RETIRED_USED_CYCLES +PMC1 UOPS_RETIRED_STALL_CYCLES +PMC2 CPU_CLOCK_UNHALTED_TOTAL_CYCLES +PMC3:EDGEDETECT UOPS_RETIRED_STALL_CYCLES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Used cycles ratio [%] 100*PMC0/PMC2 +Unused cycles ratio [%] 100*PMC1/PMC2 +Avg stall duration [cycles] PMC1/PMC3:EDGEDETECT + + +LONG +Formulas: +Used cycles ratio [%] = 100*UOPS_RETIRED_USED_CYCLES/CPU_CLK_UNHALTED_CORE +Unused cycles ratio [%] = 100*UOPS_RETIRED_STALL_CYCLES/CPU_CLK_UNHALTED_CORE +Avg stall duration [cycles] = UOPS_RETIRED_STALL_CYCLES/UOPS_RETIRED_STALL_CYCLES:EDGEDETECT +- +This performance group returns the ratios of used and unused cycles regarding +the retirement stage in the pipeline (re-order buffer). Used cycles are all +cycles where uOPs are retired while unused cycles refer to pipeline stalls. +Moreover, the group calculates the average stall duration in cycles. diff --git a/collectors/likwid/groups/skylakeX/BRANCH.txt b/collectors/likwid/groups/skylakeX/BRANCH.txt new file mode 100644 index 0000000..b8d41b2 --- /dev/null +++ b/collectors/likwid/groups/skylakeX/BRANCH.txt @@ -0,0 +1,31 @@ +SHORT Branch prediction miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 BR_INST_RETIRED_ALL_BRANCHES +PMC1 BR_MISP_RETIRED_ALL_BRANCHES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Branch rate PMC0/FIXC0 +Branch misprediction rate PMC1/FIXC0 +Branch misprediction ratio PMC1/PMC0 +Instructions per branch FIXC0/PMC0 + +LONG +Formulas: +Branch rate = BR_INST_RETIRED_ALL_BRANCHES/INSTR_RETIRED_ANY +Branch misprediction rate = BR_MISP_RETIRED_ALL_BRANCHES/INSTR_RETIRED_ANY +Branch misprediction ratio = BR_MISP_RETIRED_ALL_BRANCHES/BR_INST_RETIRED_ALL_BRANCHES +Instructions per branch = INSTR_RETIRED_ANY/BR_INST_RETIRED_ALL_BRANCHES +- +The rates state how often on average a branch or a mispredicted branch occurred +per instruction retired in total. The branch misprediction ratio sets directly +into relation what ratio of all branch instruction where mispredicted. +Instructions per branch is 1/branch rate. + diff --git a/collectors/likwid/groups/skylakeX/CACHES.txt b/collectors/likwid/groups/skylakeX/CACHES.txt new file mode 100644 index 0000000..c700dd4 --- /dev/null +++ b/collectors/likwid/groups/skylakeX/CACHES.txt @@ -0,0 +1,143 @@ +SHORT Cache bandwidth in MBytes/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 L1D_REPLACEMENT +PMC1 L1D_M_EVICT +PMC2 L2_LINES_IN_ALL +PMC3 L2_TRANS_L2_WB +CBOX0C1 LLC_VICTIMS_M_STATE +CBOX1C1 LLC_VICTIMS_M_STATE +CBOX2C1 LLC_VICTIMS_M_STATE +CBOX3C1 LLC_VICTIMS_M_STATE +CBOX4C1 LLC_VICTIMS_M_STATE +CBOX5C1 LLC_VICTIMS_M_STATE +CBOX6C1 LLC_VICTIMS_M_STATE +CBOX7C1 LLC_VICTIMS_M_STATE +CBOX8C1 LLC_VICTIMS_M_STATE +CBOX9C1 LLC_VICTIMS_M_STATE +CBOX10C1 LLC_VICTIMS_M_STATE +CBOX11C1 LLC_VICTIMS_M_STATE +CBOX12C1 LLC_VICTIMS_M_STATE +CBOX13C1 LLC_VICTIMS_M_STATE +CBOX14C1 LLC_VICTIMS_M_STATE +CBOX15C1 LLC_VICTIMS_M_STATE +CBOX16C1 LLC_VICTIMS_M_STATE +CBOX17C1 LLC_VICTIMS_M_STATE +CBOX18C1 LLC_VICTIMS_M_STATE +CBOX19C1 LLC_VICTIMS_M_STATE +CBOX20C1 LLC_VICTIMS_M_STATE +CBOX21C1 LLC_VICTIMS_M_STATE +CBOX22C1 LLC_VICTIMS_M_STATE +CBOX23C1 LLC_VICTIMS_M_STATE +CBOX24C1 LLC_VICTIMS_M_STATE +CBOX25C1 LLC_VICTIMS_M_STATE +CBOX26C1 LLC_VICTIMS_M_STATE +CBOX27C1 LLC_VICTIMS_M_STATE +CBOX0C0 LLC_LOOKUP_DATA_READ +CBOX1C0 LLC_LOOKUP_DATA_READ +CBOX2C0 LLC_LOOKUP_DATA_READ +CBOX3C0 LLC_LOOKUP_DATA_READ +CBOX4C0 LLC_LOOKUP_DATA_READ +CBOX5C0 LLC_LOOKUP_DATA_READ +CBOX6C0 LLC_LOOKUP_DATA_READ +CBOX7C0 LLC_LOOKUP_DATA_READ +CBOX8C0 LLC_LOOKUP_DATA_READ +CBOX9C0 LLC_LOOKUP_DATA_READ +CBOX10C0 LLC_LOOKUP_DATA_READ +CBOX11C0 LLC_LOOKUP_DATA_READ +CBOX12C0 LLC_LOOKUP_DATA_READ +CBOX13C0 LLC_LOOKUP_DATA_READ +CBOX14C0 LLC_LOOKUP_DATA_READ +CBOX15C0 LLC_LOOKUP_DATA_READ +CBOX16C0 LLC_LOOKUP_DATA_READ +CBOX17C0 LLC_LOOKUP_DATA_READ +CBOX18C0 LLC_LOOKUP_DATA_READ +CBOX19C0 LLC_LOOKUP_DATA_READ +CBOX20C0 LLC_LOOKUP_DATA_READ +CBOX21C0 LLC_LOOKUP_DATA_READ +CBOX22C0 LLC_LOOKUP_DATA_READ +CBOX23C0 LLC_LOOKUP_DATA_READ +CBOX24C0 LLC_LOOKUP_DATA_READ +CBOX25C0 LLC_LOOKUP_DATA_READ +CBOX26C0 LLC_LOOKUP_DATA_READ +CBOX27C0 LLC_LOOKUP_DATA_READ +MBOX0C0 CAS_COUNT_RD +MBOX0C1 CAS_COUNT_WR +MBOX1C0 CAS_COUNT_RD +MBOX1C1 CAS_COUNT_WR +MBOX2C0 CAS_COUNT_RD +MBOX2C1 CAS_COUNT_WR +MBOX3C0 CAS_COUNT_RD +MBOX3C1 CAS_COUNT_WR +MBOX4C0 CAS_COUNT_RD +MBOX4C1 CAS_COUNT_WR +MBOX5C0 CAS_COUNT_RD +MBOX5C1 CAS_COUNT_WR + + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L2 to L1 load bandwidth [MBytes/s] 1.0E-06*PMC0*64.0/time +L2 to L1 load data volume [GBytes] 1.0E-09*PMC0*64.0 +L1 to L2 evict bandwidth [MBytes/s] 1.0E-06*PMC1*64.0/time +L1 to L2 evict data volume [GBytes] 1.0E-09*PMC1*64.0 +L1 to/from L2 bandwidth [MBytes/s] 1.0E-06*(PMC0+PMC1)*64.0/time +L1 to/from L2 data volume [GBytes] 1.0E-09*(PMC0+PMC1)*64.0 +L3 to L2 load bandwidth [MBytes/s] 1.0E-06*PMC2*64.0/time +L3 to L2 load data volume [GBytes] 1.0E-09*PMC2*64.0 +L2 to L3 evict bandwidth [MBytes/s] 1.0E-06*PMC3*64.0/time +L2 to L3 evict data volume [GBytes] 1.0E-09*PMC3*64.0 +L2 to/from L3 bandwidth [MBytes/s] 1.0E-06*(PMC2+PMC3)*64.0/time +L2 to/from L3 data volume [GBytes] 1.0E-09*(PMC2+PMC3)*64.0 +System to L3 bandwidth [MBytes/s] 1.0E-06*(CBOX0C0+CBOX1C0+CBOX2C0+CBOX3C0+CBOX4C0+CBOX5C0+CBOX6C0+CBOX7C0+CBOX8C0+CBOX9C0+CBOX10C0+CBOX11C0+CBOX12C0+CBOX13C0+CBOX14C0+CBOX15C0+CBOX16C0+CBOX17C0+CBOX18C0+CBOX19C0+CBOX20C0+CBOX21C0+CBOX22C0+CBOX23C0+CBOX24C0+CBOX25C0+CBOX26C0+CBOX27C0)*64.0/time +System to L3 data volume [GBytes] 1.0E-09*(CBOX0C0+CBOX1C0+CBOX2C0+CBOX3C0+CBOX4C0+CBOX5C0+CBOX6C0+CBOX7C0+CBOX8C0+CBOX9C0+CBOX10C0+CBOX11C0+CBOX12C0+CBOX13C0+CBOX14C0+CBOX15C0+CBOX16C0+CBOX17C0+CBOX18C0+CBOX19C0+CBOX20C0+CBOX21C0+CBOX22C0+CBOX23C0+CBOX24C0+CBOX25C0+CBOX26C0+CBOX27C0)*64.0 +L3 to system bandwidth [MBytes/s] 1.0E-06*(CBOX0C1+CBOX1C1+CBOX2C1+CBOX3C1+CBOX4C1+CBOX5C1+CBOX6C1+CBOX7C1+CBOX8C1+CBOX9C1+CBOX10C1+CBOX11C1+CBOX12C1+CBOX13C1+CBOX14C1+CBOX15C1+CBOX16C1+CBOX17C1+CBOX18C1+CBOX19C1+CBOX20C1+CBOX21C1+CBOX22C1+CBOX23C1+CBOX24C1+CBOX25C1+CBOX26C1+CBOX27C1)*64/time +L3 to system data volume [GBytes] 1.0E-09*(CBOX0C1+CBOX1C1+CBOX2C1+CBOX3C1+CBOX4C1+CBOX5C1+CBOX6C1+CBOX7C1+CBOX8C1+CBOX9C1+CBOX10C1+CBOX11C1+CBOX12C1+CBOX13C1+CBOX14C1+CBOX15C1+CBOX16C1+CBOX17C1+CBOX18C1+CBOX19C1+CBOX20C1+CBOX21C1+CBOX22C1+CBOX23C1+CBOX24C1+CBOX25C1+CBOX26C1+CBOX27C1)*64 +L3 to/from system bandwidth [MBytes/s] 1.0E-06*(CBOX0C0+CBOX1C0+CBOX2C0+CBOX3C0+CBOX4C0+CBOX5C0+CBOX6C0+CBOX7C0+CBOX8C0+CBOX9C0+CBOX10C0+CBOX11C0+CBOX12C0+CBOX13C0+CBOX14C0+CBOX15C0+CBOX16C0+CBOX17C0+CBOX18C0+CBOX19C0+CBOX20C0+CBOX21C0+CBOX22C0+CBOX23C0+CBOX24C0+CBOX25C0+CBOX26C0+CBOX27C0+CBOX0C1+CBOX1C1+CBOX2C1+CBOX3C1+CBOX4C1+CBOX5C1+CBOX6C1+CBOX7C1+CBOX8C1+CBOX9C1+CBOX10C1+CBOX11C1+CBOX12C1+CBOX13C1+CBOX14C1+CBOX15C1+CBOX16C1+CBOX17C1+CBOX18C1+CBOX19C1+CBOX20C1+CBOX21C1+CBOX22C1+CBOX23C1+CBOX24C1+CBOX25C1+CBOX26C1+CBOX27C1)*64.0/time +L3 to/from system data volume [GBytes] 1.0E-09*(CBOX0C0+CBOX1C0+CBOX2C0+CBOX3C0+CBOX4C0+CBOX5C0+CBOX6C0+CBOX7C0+CBOX8C0+CBOX9C0+CBOX10C0+CBOX11C0+CBOX12C0+CBOX13C0+CBOX14C0+CBOX15C0+CBOX16C0+CBOX17C0+CBOX18C0+CBOX19C0+CBOX20C0+CBOX21C0+CBOX22C0+CBOX23C0+CBOX24C0+CBOX25C0+CBOX26C0+CBOX27C0+CBOX0C1+CBOX1C1+CBOX2C1+CBOX3C1+CBOX4C1+CBOX5C1+CBOX6C1+CBOX7C1+CBOX8C1+CBOX9C1+CBOX10C1+CBOX11C1+CBOX12C1+CBOX13C1+CBOX14C1+CBOX15C1+CBOX16C1+CBOX17C1+CBOX18C1+CBOX19C1+CBOX20C1+CBOX21C1+CBOX22C1+CBOX23C1+CBOX24C1+CBOX25C1+CBOX26C1+CBOX27C1)*64.0 +Memory read bandwidth [MBytes/s] 1.0E-06*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0)*64.0/time +Memory read data volume [GBytes] 1.0E-09*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0)*64.0 +Memory write bandwidth [MBytes/s] 1.0E-06*(MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1)*64.0/time +Memory write data volume [GBytes] 1.0E-09*(MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1)*64.0 +Memory bandwidth [MBytes/s] 1.0E-06*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1)*64.0/time +Memory data volume [GBytes] 1.0E-09*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1)*64.0 + +LONG +Formulas: +L2 to L1 load bandwidth [MBytes/s] = 1.0E-06*L1D_REPLACEMENT*64/time +L2 to L1 load data volume [GBytes] = 1.0E-09*L1D_REPLACEMENT*64 +L1 to L2 evict bandwidth [MBytes/s] = 1.0E-06*L1D_M_EVICT*64/time +L1 to L2 evict data volume [GBytes] = 1.0E-09*L1D_M_EVICT*64 +L1 to/from L2 bandwidth [MBytes/s] = 1.0E-06*(L1D_REPLACEMENT+L1D_M_EVICT)*64/time +L1 to/from L2 data volume [GBytes] = 1.0E-09*(L1D_REPLACEMENT+L1D_M_EVICT)*64 +L3 to L2 load bandwidth [MBytes/s] = 1.0E-06*L2_LINES_IN_ALL*64/time +L3 to L2 load data volume [GBytes] = 1.0E-09*L2_LINES_IN_ALL*64 +L2 to L3 evict bandwidth [MBytes/s] = 1.0E-06*L2_TRANS_L2_WB*64/time +L2 to L3 evict data volume [GBytes] = 1.0E-09*L2_TRANS_L2_WB*64 +L2 to/from L3 bandwidth [MBytes/s] = 1.0E-06*(L2_LINES_IN_ALL+L2_TRANS_L2_WB)*64/time +L2 to/from L3 data volume [GBytes] = 1.0E-09*(L2_LINES_IN_ALL+L2_TRANS_L2_WB)*64 +System to L3 bandwidth [MBytes/s] = 1.0E-06*(SUM(LLC_LOOKUP_DATA_READ))*64/time +System to L3 data volume [GBytes] = 1.0E-09*(SUM(LLC_LOOKUP_DATA_READ))*64 +L3 to system bandwidth [MBytes/s] = 1.0E-06*(SUM(LLC_VICTIMS_M_STATE))*64/time +L3 to system data volume [GBytes] = 1.0E-09*(SUM(LLC_VICTIMS_M_STATE))*64 +L3 to/from system bandwidth [MBytes/s] = 1.0E-06*(SUM(LLC_LOOKUP_DATA_READ)+SUM(LLC_VICTIMS_M_STATE))*64/time +L3 to/from system data volume [GBytes] = 1.0E-09*(SUM(LLC_LOOKUP_DATA_READ)+SUM(LLC_VICTIMS_M_STATE))*64 +Memory read bandwidth [MBytes/s] = 1.0E-06*(SUM(CAS_COUNT_RD))*64.0/time +Memory read data volume [GBytes] = 1.0E-09*(SUM(CAS_COUNT_RD))*64.0 +Memory write bandwidth [MBytes/s] = 1.0E-06*(SUM(CAS_COUNT_WR))*64.0/time +Memory write data volume [GBytes] = 1.0E-09*(SUM(CAS_COUNT_WR))*64.0 +Memory bandwidth [MBytes/s] = 1.0E-06*(SUM(CAS_COUNT_RD)+SUM(CAS_COUNT_WR))*64.0/time +Memory data volume [GBytes] = 1.0E-09*(SUM(CAS_COUNT_RD)+SUM(CAS_COUNT_WR))*64.0 +- +Group to measure cache transfers between L1 and Memory. Please notice that the +L3 to/from system metrics contain any traffic to the system (memory, +Intel QPI, etc.) but don't seem to handle anything because commonly memory read +bandwidth and L3 to L2 bandwidth is higher as the memory to L3 bandwidth. + diff --git a/collectors/likwid/groups/skylakeX/CLOCK.txt b/collectors/likwid/groups/skylakeX/CLOCK.txt new file mode 100644 index 0000000..b81bee6 --- /dev/null +++ b/collectors/likwid/groups/skylakeX/CLOCK.txt @@ -0,0 +1,26 @@ +SHORT Power and Energy consumption + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PWR0 PWR_PKG_ENERGY +UBOXFIX UNCORE_CLOCK + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +Uncore Clock [MHz] 1.E-06*UBOXFIX/time +CPI FIXC1/FIXC0 +Energy [J] PWR0 +Power [W] PWR0/time + +LONG +Formulas: +Power = PWR_PKG_ENERGY / time +Uncore Clock [MHz] = 1.E-06 * UNCORE_CLOCK / time +- +Broadwell implements the new RAPL interface. This interface enables to +monitor the consumed energy on the package (socket) level. + diff --git a/collectors/likwid/groups/skylakeX/CYCLE_ACTIVITY.txt b/collectors/likwid/groups/skylakeX/CYCLE_ACTIVITY.txt new file mode 100644 index 0000000..c432a44 --- /dev/null +++ b/collectors/likwid/groups/skylakeX/CYCLE_ACTIVITY.txt @@ -0,0 +1,38 @@ +SHORT Cycle Activities + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 CYCLE_ACTIVITY_CYCLES_L2_PENDING +PMC1 CYCLE_ACTIVITY_CYCLES_LDM_PENDING +PMC2 CYCLE_ACTIVITY_CYCLES_L1D_PENDING +PMC3 CYCLE_ACTIVITY_CYCLES_NO_EXECUTE + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Cycles without execution [%] (PMC3/FIXC1)*100 +Cycles without execution due to L1D [%] (PMC2/FIXC1)*100 +Cycles without execution due to L2 [%] (PMC0/FIXC1)*100 +Cycles without execution due to memory loads [%] (PMC1/FIXC1)*100 + +LONG +Formulas: +Cycles without execution [%] = CYCLE_ACTIVITY_CYCLES_NO_EXECUTE/CPU_CLK_UNHALTED_CORE*100 +Cycles with stalls due to L1D [%] = CYCLE_ACTIVITY_CYCLES_L1D_PENDING/CPU_CLK_UNHALTED_CORE*100 +Cycles with stalls due to L2 [%] = CYCLE_ACTIVITY_CYCLES_L2_PENDING/CPU_CLK_UNHALTED_CORE*100 +Cycles without execution due to memory loads [%] = CYCLE_ACTIVITY_CYCLES_LDM_PENDING/CPU_CLK_UNHALTED_CORE*100 +-- +This performance group measures the cycles while waiting for data from the cache +and memory hierarchy. +CYCLE_ACTIVITY_CYCLES_NO_EXECUTE: Counts number of cycles nothing is executed on +any execution port. +CYCLE_ACTIVITY_CYCLES_L1D_PENDING: Cycles while L1 cache miss demand load is +outstanding. +CYCLE_ACTIVITY_CYCLES_L2_PENDING: Cycles while L2 cache miss demand load is +outstanding. +CYCLE_ACTIVITY_CYCLES_LDM_PENDING: Cycles while memory subsystem has an +outstanding load. diff --git a/collectors/likwid/groups/skylakeX/CYCLE_STALLS.txt b/collectors/likwid/groups/skylakeX/CYCLE_STALLS.txt new file mode 100644 index 0000000..795aeb9 --- /dev/null +++ b/collectors/likwid/groups/skylakeX/CYCLE_STALLS.txt @@ -0,0 +1,45 @@ +SHORT Cycle Activities (Stalls) + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 CYCLE_ACTIVITY_STALLS_L2_PENDING +PMC1 CYCLE_ACTIVITY_STALLS_LDM_PENDING +PMC2 CYCLE_ACTIVITY_STALLS_L1D_PENDING +PMC3 CYCLE_ACTIVITY_STALLS_TOTAL + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Total execution stalls PMC3 +Stalls caused by L1D misses [%] (PMC2/PMC3)*100 +Stalls caused by L2 misses [%] (PMC0/PMC3)*100 +Stalls caused by memory loads [%] (PMC1/PMC3)*100 +Execution stall rate [%] (PMC3/FIXC1)*100 +Stalls caused by L1D misses rate [%] (PMC2/FIXC1)*100 +Stalls caused by L2 misses rate [%] (PMC0/FIXC1)*100 +Stalls caused by memory loads rate [%] (PMC1/FIXC1)*100 + +LONG +Formulas: +Total execution stalls = CYCLE_ACTIVITY_STALLS_TOTAL +Stalls caused by L1D misses [%] = (CYCLE_ACTIVITY_STALLS_L1D_PENDING/CYCLE_ACTIVITY_STALLS_TOTAL)*100 +Stalls caused by L2 misses [%] = (CYCLE_ACTIVITY_STALLS_L2_PENDING/CYCLE_ACTIVITY_STALLS_TOTAL)*100 +Stalls caused by memory loads [%] = (CYCLE_ACTIVITY_STALLS_LDM_PENDING/CYCLE_ACTIVITY_STALLS_TOTAL)*100 +Execution stall rate [%] = (CYCLE_ACTIVITY_STALLS_TOTAL/CPU_CLK_UNHALTED_CORE)*100 +Stalls caused by L1D misses rate [%] = (CYCLE_ACTIVITY_STALLS_L1D_PENDING/CPU_CLK_UNHALTED_CORE)*100 +Stalls caused by L2 misses rate [%] = (CYCLE_ACTIVITY_STALLS_L2_PENDING/CPU_CLK_UNHALTED_CORE)*100 +Stalls caused by memory loads rate [%] = (CYCLE_ACTIVITY_STALLS_LDM_PENDING/CPU_CLK_UNHALTED_CORE)*100 +-- +This performance group measures the stalls caused by data traffic in the cache +hierarchy. +CYCLE_ACTIVITY_STALLS_TOTAL: Total execution stalls. +CYCLE_ACTIVITY_STALLS_L1D_PENDING: Execution stalls while L1 cache miss demand +load is outstanding. +CYCLE_ACTIVITY_STALLS_L2_PENDING: Execution stalls while L2 cache miss demand +load is outstanding. +CYCLE_ACTIVITY_STALLS_LDM_PENDING: Execution stalls while memory subsystem has +an outstanding load. diff --git a/collectors/likwid/groups/skylakeX/DATA.txt b/collectors/likwid/groups/skylakeX/DATA.txt new file mode 100644 index 0000000..4e6e938 --- /dev/null +++ b/collectors/likwid/groups/skylakeX/DATA.txt @@ -0,0 +1,22 @@ +SHORT Load to store ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 MEM_INST_RETIRED_ALL_LOADS +PMC1 MEM_INST_RETIRED_ALL_STORES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Load to store ratio PMC0/PMC1 + +LONG +Formulas: +Load to store ratio = MEM_INST_RETIRED_ALL_LOADS/MEM_INST_RETIRED_ALL_STORES +- +This is a metric to determine your load to store ratio. + diff --git a/collectors/likwid/groups/skylakeX/DIVIDE.txt b/collectors/likwid/groups/skylakeX/DIVIDE.txt new file mode 100644 index 0000000..40b4ab6 --- /dev/null +++ b/collectors/likwid/groups/skylakeX/DIVIDE.txt @@ -0,0 +1,24 @@ +SHORT Divide unit information + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 ARITH_DIVIDER_COUNT +PMC1 ARITH_DIVIDER_ACTIVE + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Number of divide ops PMC0 +Avg. divide unit usage duration PMC1/PMC0 + +LONG +Formulas: +Number of divide ops = ARITH_DIVIDER_COUNT +Avg. divide unit usage duration = ARITH_DIVIDER_ACTIVE/ARITH_DIVIDER_COUNT +- +This performance group measures the average latency of divide operations diff --git a/collectors/likwid/groups/skylakeX/ENERGY.txt b/collectors/likwid/groups/skylakeX/ENERGY.txt new file mode 100644 index 0000000..fe7829f --- /dev/null +++ b/collectors/likwid/groups/skylakeX/ENERGY.txt @@ -0,0 +1,35 @@ +SHORT Power and Energy consumption + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +TMP0 TEMP_CORE +PWR0 PWR_PKG_ENERGY +PWR1 PWR_PP0_ENERGY +PWR3 PWR_DRAM_ENERGY + + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Temperature [C] TMP0 +Energy [J] PWR0 +Power [W] PWR0/time +Energy PP0 [J] PWR1 +Power PP0 [W] PWR1/time +Energy DRAM [J] PWR3 +Power DRAM [W] PWR3/time + +LONG +Formulas: +Power = PWR_PKG_ENERGY / time +Power PP0 = PWR_PP0_ENERGY / time +Power DRAM = PWR_DRAM_ENERGY / time +- +Broadwell implements the new RAPL interface. This interface enables to +monitor the consumed energy on the package (socket) and DRAM level. + diff --git a/collectors/likwid/groups/skylakeX/FLOPS_AVX.txt b/collectors/likwid/groups/skylakeX/FLOPS_AVX.txt new file mode 100644 index 0000000..e44a913 --- /dev/null +++ b/collectors/likwid/groups/skylakeX/FLOPS_AVX.txt @@ -0,0 +1,25 @@ +SHORT Packed AVX MFLOP/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE +PMC1 FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE +PMC2 FP_ARITH_INST_RETIRED_512B_PACKED_SINGLE +PMC3 FP_ARITH_INST_RETIRED_512B_PACKED_DOUBLE + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Packed SP [MFLOP/s] 1.0E-06*(PMC0*8.0+PMC2*16.0)/time +Packed DP [MFLOP/s] 1.0E-06*(PMC1*4.0+PMC3*8.0)/time + +LONG +Formulas: +Packed SP [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE*8+FP_ARITH_INST_RETIRED_512B_PACKED_SINGLE*16)/runtime +Packed DP [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE*4+FP_ARITH_INST_RETIRED_512B_PACKED_DOUBLE*8)/runtime +- +Packed 32b AVX FLOPs rates. diff --git a/collectors/likwid/groups/skylakeX/FLOPS_DP.txt b/collectors/likwid/groups/skylakeX/FLOPS_DP.txt new file mode 100644 index 0000000..177cff2 --- /dev/null +++ b/collectors/likwid/groups/skylakeX/FLOPS_DP.txt @@ -0,0 +1,34 @@ +SHORT Double Precision MFLOP/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 FP_ARITH_INST_RETIRED_128B_PACKED_DOUBLE +PMC1 FP_ARITH_INST_RETIRED_SCALAR_DOUBLE +PMC2 FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE +PMC3 FP_ARITH_INST_RETIRED_512B_PACKED_DOUBLE + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +DP [MFLOP/s] 1.0E-06*(PMC0*2.0+PMC1+PMC2*4.0+PMC3*8.0)/time +AVX DP [MFLOP/s] 1.0E-06*(PMC2*4.0+PMC3*8.0)/time +AVX512 DP [MFLOP/s] 1.0E-06*(PMC3*8.0)/time +Packed [MUOPS/s] 1.0E-06*(PMC0+PMC2+PMC3)/time +Scalar [MUOPS/s] 1.0E-06*PMC1/time +Vectorization ratio 100*(PMC0+PMC2+PMC3)/(PMC0+PMC1+PMC2+PMC3) + +LONG +Formulas: +DP [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_128B_PACKED_DOUBLE*2+FP_ARITH_INST_RETIRED_SCALAR_DOUBLE+FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE*4+FP_ARITH_INST_RETIRED_512B_PACKED_DOUBLE*8)/runtime +AVX DP [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE*4+FP_ARITH_INST_RETIRED_512B_PACKED_DOUBLE*8)/runtime +AVX512 DP [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_512B_PACKED_DOUBLE*8)/runtime +Packed [MUOPS/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_128B_PACKED_DOUBLE+FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE+FP_ARITH_INST_RETIRED_512B_PACKED_DOUBLE)/runtime +Scalar [MUOPS/s] = 1.0E-06*FP_ARITH_INST_RETIRED_SCALAR_DOUBLE/runtime +Vectorization ratio = 100*(FP_ARITH_INST_RETIRED_128B_PACKED_DOUBLE+FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE+FP_ARITH_INST_RETIRED_512B_PACKED_DOUBLE)/(FP_ARITH_INST_RETIRED_SCALAR_DOUBLE+FP_ARITH_INST_RETIRED_128B_PACKED_DOUBLE+FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE+FP_ARITH_INST_RETIRED_512B_PACKED_DOUBLE) +- +SSE scalar and packed double precision FLOP rates. + diff --git a/collectors/likwid/groups/skylakeX/FLOPS_SP.txt b/collectors/likwid/groups/skylakeX/FLOPS_SP.txt new file mode 100644 index 0000000..01d98c2 --- /dev/null +++ b/collectors/likwid/groups/skylakeX/FLOPS_SP.txt @@ -0,0 +1,34 @@ +SHORT Single Precision MFLOP/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 FP_ARITH_INST_RETIRED_128B_PACKED_SINGLE +PMC1 FP_ARITH_INST_RETIRED_SCALAR_SINGLE +PMC2 FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE +PMC3 FP_ARITH_INST_RETIRED_512B_PACKED_SINGLE + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +SP [MFLOP/s] 1.0E-06*(PMC0*4.0+PMC1+PMC2*8.0+PMC3*16.0)/time +AVX SP [MFLOP/s] 1.0E-06*(PMC2*8.0+PMC3*16.0)/time +AVX512 SP [MFLOP/s] 1.0E-06*(PMC3*16.0)/time +Packed [MUOPS/s] 1.0E-06*(PMC0+PMC2+PMC3)/time +Scalar [MUOPS/s] 1.0E-06*PMC1/time +Vectorization ratio 100*(PMC0+PMC2+PMC3)/(PMC0+PMC1+PMC2+PMC3) + +LONG +Formulas: +SP [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_128B_PACKED_SINGLE*4+FP_ARITH_INST_RETIRED_SCALAR_SINGLE+FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE*8+FP_ARITH_INST_RETIRED_512B_PACKED_SINGLE*16)/runtime +AVX SP [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE*8+FP_ARITH_INST_RETIRED_512B_PACKED_SINGLE*16)/runtime +AVX512 SP [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_512B_PACKED_SINGLE*16)/runtime +Packed [MUOPS/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_128B_PACKED_SINGLE+FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE+FP_ARITH_INST_RETIRED_512B_PACKED_SINGLE)/runtime +Scalar [MUOPS/s] = 1.0E-06*FP_ARITH_INST_RETIRED_SCALAR_SINGLE/runtime +Vectorization ratio [%] = 100*(FP_ARITH_INST_RETIRED_128B_PACKED_SINGLE+FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE+FP_ARITH_INST_RETIRED_512B_PACKED_SINGLE)/(FP_ARITH_INST_RETIRED_SCALAR_SINGLE+FP_ARITH_INST_RETIRED_128B_PACKED_SINGLE+FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE+FP_ARITH_INST_RETIRED_512B_PACKED_SINGLE) +- +SSE scalar and packed single precision FLOP rates. + diff --git a/collectors/likwid/groups/skylakeX/L2.txt b/collectors/likwid/groups/skylakeX/L2.txt new file mode 100644 index 0000000..1a92a95 --- /dev/null +++ b/collectors/likwid/groups/skylakeX/L2.txt @@ -0,0 +1,38 @@ +SHORT L2 cache bandwidth in MBytes/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 L1D_REPLACEMENT +PMC1 L1D_M_EVICT +PMC2 ICACHE_64B_IFTAG_MISS + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L2D load bandwidth [MBytes/s] 1.0E-06*PMC0*64.0/time +L2D load data volume [GBytes] 1.0E-09*PMC0*64.0 +L2D evict bandwidth [MBytes/s] 1.0E-06*PMC1*64.0/time +L2D evict data volume [GBytes] 1.0E-09*PMC1*64.0 +L2 bandwidth [MBytes/s] 1.0E-06*(PMC0+PMC1+PMC2)*64.0/time +L2 data volume [GBytes] 1.0E-09*(PMC0+PMC1+PMC2)*64.0 + +LONG +Formulas: +L2D load bandwidth [MBytes/s] = 1.0E-06*L1D_REPLACEMENT*64.0/time +L2D load data volume [GBytes] = 1.0E-09*L1D_REPLACEMENT*64.0 +L2D evict bandwidth [MBytes/s] = 1.0E-06*L1D_M_EVICT*64.0/time +L2D evict data volume [GBytes] = 1.0E-09*L1D_M_EVICT*64.0 +L2 bandwidth [MBytes/s] = 1.0E-06*(L1D_REPLACEMENT+L1D_M_EVICT+ICACHE_64B_IFTAG_MISS)*64/time +L2 data volume [GBytes] = 1.0E-09*(L1D_REPLACEMENT+L1D_M_EVICT+ICACHE_64B_IFTAG_MISS)*64 +- +Profiling group to measure L2 cache bandwidth. The bandwidth is computed by the +number of cache line allocated in the L1 and the number of modified cache lines +evicted from the L1. The group also output total data volume transferred between +L2 and L1. Note that this bandwidth also includes data transfers due to a write +allocate load on a store miss in L1 and traffic caused by misses in the +L1 instruction cache. + diff --git a/collectors/likwid/groups/skylakeX/L2CACHE.txt b/collectors/likwid/groups/skylakeX/L2CACHE.txt new file mode 100644 index 0000000..9b5dd4b --- /dev/null +++ b/collectors/likwid/groups/skylakeX/L2CACHE.txt @@ -0,0 +1,34 @@ +SHORT L2 cache miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 L2_TRANS_ALL_REQUESTS +PMC1 L2_RQSTS_MISS + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L2 request rate PMC0/FIXC0 +L2 miss rate PMC1/FIXC0 +L2 miss ratio PMC1/PMC0 + +LONG +Formulas: +L2 request rate = L2_TRANS_ALL_REQUESTS/INSTR_RETIRED_ANY +L2 miss rate = L2_RQSTS_MISS/INSTR_RETIRED_ANY +L2 miss ratio = L2_RQSTS_MISS/L2_TRANS_ALL_REQUESTS +- +This group measures the locality of your data accesses with regard to the +L2 cache. L2 request rate tells you how data intensive your code is +or how many data accesses you have on average per instruction. +The L2 miss rate gives a measure how often it was necessary to get +cache lines from memory. And finally L2 miss ratio tells you how many of your +memory references required a cache line to be loaded from a higher level. +While the# data cache miss rate might be given by your algorithm you should +try to get data cache miss ratio as low as possible by increasing your cache reuse. + + diff --git a/collectors/likwid/groups/skylakeX/L3.txt b/collectors/likwid/groups/skylakeX/L3.txt new file mode 100644 index 0000000..219f932 --- /dev/null +++ b/collectors/likwid/groups/skylakeX/L3.txt @@ -0,0 +1,48 @@ +SHORT L3 cache bandwidth in MBytes/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 L2_LINES_IN_ALL +PMC1 L2_TRANS_L2_WB +PMC2 IDI_MISC_WB_DOWNGRADE +PMC3 IDI_MISC_WB_UPGRADE + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L3 load bandwidth [MBytes/s] 1.0E-06*PMC0*64.0/time +L3 load data volume [GBytes] 1.0E-09*PMC0*64.0 +L3 evict bandwidth [MBytes/s] 1.0E-06*PMC3*64.0/time +L3 evict data volume [GBytes] 1.0E-09*PMC3*64.0 +L3|MEM evict bandwidth [MBytes/s] 1.0E-06*PMC1*64.0/time +L3|MEM evict data volume [GBytes] 1.0E-09*PMC1*64.0 +Dropped CLs bandwidth [MBytes/s] 1.0E-6*PMC2*64.0/time +Dropped CLs data volume [GBytes] 1.0E-9*PMC2*64.0 +L3 bandwidth [MBytes/s] 1.0E-06*(PMC0+PMC1)*64.0/time +L3 data volume [GBytes] 1.0E-09*(PMC0+PMC1)*64.0 + +LONG +Formulas: +L3 load bandwidth [MBytes/s] = 1.0E-06*L2_LINES_IN_ALL*64.0/time +L3 load data volume [GBytes] = 1.0E-09*L2_LINES_IN_ALL*64.0 +L3 evict bandwidth [MBytes/s] = 1.0E-06*IDI_MISC_WB_UPGRADE*64.0/time +L3 evict data volume [GBytes] = 1.0E-09*IDI_MISC_WB_UPGRADE*64.0 +Dropped CLs bandwidth [MBytes/s] = 1.0E-6*IDI_MISC_WB_DOWNGRADE*64.0/time +Dropped CLs data volume [GBytes] = 1.0E-9*IDI_MISC_WB_DOWNGRADE*64.0 +L3|MEM evict bandwidth [MBytes/s] = 1.0E-06*L2_TRANS_L2_WB*64.0/time +L3|MEM evict data volume [GBytes] = 1.0E-09*L2_TRANS_L2_WB*64.0 +L3 bandwidth [MBytes/s] = 1.0E-06*(L2_LINES_IN_ALL+L2_TRANS_L2_WB)*64/time +L3 data volume [GBytes] = 1.0E-09*(L2_LINES_IN_ALL+L2_TRANS_L2_WB)*64 +-- +Profiling group to measure L3 cache bandwidth and data volume. For Intel Skylake +or Cascadelake, the L3 is a victim cache. This means that all data is loaded +from memory directly into the L2 cache (if L3 prefetcher is inactive). Modified +data in L2 is evicted to L3 (additional data transfer due to non-inclusivenss of +L3 can be measured). Clean cache lines (only loaded data) might get dropped in +L2 to reduce traffic. If amount of clean cache lines is smaller than L3, it +might be evicted to L3 due to some heuristic. diff --git a/collectors/likwid/groups/skylakeX/L3CACHE.txt b/collectors/likwid/groups/skylakeX/L3CACHE.txt new file mode 100644 index 0000000..bc664d1 --- /dev/null +++ b/collectors/likwid/groups/skylakeX/L3CACHE.txt @@ -0,0 +1,35 @@ +SHORT L3 cache miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 MEM_LOAD_RETIRED_L3_HIT +PMC1 MEM_LOAD_RETIRED_L3_MISS +PMC2 UOPS_RETIRED_ALL + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L3 request rate (PMC0+PMC1)/PMC2 +L3 miss rate PMC1/PMC2 +L3 miss ratio PMC1/(PMC0+PMC1) + +LONG +Formulas: +L3 request rate = (MEM_LOAD_RETIRED_L3_HIT+MEM_LOAD_RETIRED_L3_MISS)/UOPS_RETIRED_ALL +L3 miss rate = MEM_LOAD_UOPS_RETIRED_L3_MISS/UOPS_RETIRED_ALL +L3 miss ratio = MEM_LOAD_UOPS_RETIRED_L3_MISS/(MEM_LOAD_RETIRED_L3_HIT+MEM_LOAD_RETIRED_L3_MISS) +- +This group measures the locality of your data accesses with regard to the +L3 cache. L3 request rate tells you how data intensive your code is +or how many data accesses you have on average per instruction. +The L3 miss rate gives a measure how often it was necessary to get +cache lines from memory. And finally L3 miss ratio tells you how many of your +memory references required a cache line to be loaded from a higher level. +While the data cache miss rate might be given by your algorithm you should +try to get data cache miss ratio as low as possible by increasing your cache reuse. + + diff --git a/collectors/likwid/groups/skylakeX/MEM.txt b/collectors/likwid/groups/skylakeX/MEM.txt new file mode 100644 index 0000000..3d50ecb --- /dev/null +++ b/collectors/likwid/groups/skylakeX/MEM.txt @@ -0,0 +1,48 @@ +SHORT Main memory bandwidth in MBytes/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +MBOX0C0 CAS_COUNT_RD +MBOX0C1 CAS_COUNT_WR +MBOX1C0 CAS_COUNT_RD +MBOX1C1 CAS_COUNT_WR +MBOX2C0 CAS_COUNT_RD +MBOX2C1 CAS_COUNT_WR +MBOX3C0 CAS_COUNT_RD +MBOX3C1 CAS_COUNT_WR +MBOX4C0 CAS_COUNT_RD +MBOX4C1 CAS_COUNT_WR +MBOX5C0 CAS_COUNT_RD +MBOX5C1 CAS_COUNT_WR + + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Memory read bandwidth [MBytes/s] 1.0E-06*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0)*64.0/time +Memory read data volume [GBytes] 1.0E-09*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0)*64.0 +Memory write bandwidth [MBytes/s] 1.0E-06*(MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1)*64.0/time +Memory write data volume [GBytes] 1.0E-09*(MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1)*64.0 +Memory bandwidth [MBytes/s] 1.0E-06*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1)*64.0/time +Memory data volume [GBytes] 1.0E-09*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1)*64.0 + +LONG +Formulas: +Memory read bandwidth [MBytes/s] = 1.0E-06*(SUM(MBOXxC0))*64.0/runtime +Memory read data volume [GBytes] = 1.0E-09*(SUM(MBOXxC0))*64.0 +Memory write bandwidth [MBytes/s] = 1.0E-06*(SUM(MBOXxC1))*64.0/runtime +Memory write data volume [GBytes] = 1.0E-09*(SUM(MBOXxC1))*64.0 +Memory bandwidth [MBytes/s] = 1.0E-06*(SUM(MBOXxC0)+SUM(MBOXxC1))*64.0/runtime +Memory data volume [GBytes] = 1.0E-09*(SUM(MBOXxC0)+SUM(MBOXxC1))*64.0 +- +Profiling group to measure memory bandwidth drawn by all cores of a socket. +Since this group is based on Uncore events it is only possible to measure on a +per socket base. Some of the counters may not be available on your system. +Also outputs total data volume transferred from main memory. +The same metrics are provided by the HA group. + diff --git a/collectors/likwid/groups/skylakeX/MEM_DP.txt b/collectors/likwid/groups/skylakeX/MEM_DP.txt new file mode 100644 index 0000000..d6e481a --- /dev/null +++ b/collectors/likwid/groups/skylakeX/MEM_DP.txt @@ -0,0 +1,70 @@ +SHORT Overview of arithmetic and main memory performance + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PWR0 PWR_PKG_ENERGY +PWR3 PWR_DRAM_ENERGY +PMC0 FP_ARITH_INST_RETIRED_128B_PACKED_DOUBLE +PMC1 FP_ARITH_INST_RETIRED_SCALAR_DOUBLE +PMC2 FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE +PMC3 FP_ARITH_INST_RETIRED_512B_PACKED_DOUBLE +MBOX0C0 CAS_COUNT_RD +MBOX0C1 CAS_COUNT_WR +MBOX1C0 CAS_COUNT_RD +MBOX1C1 CAS_COUNT_WR +MBOX2C0 CAS_COUNT_RD +MBOX2C1 CAS_COUNT_WR +MBOX3C0 CAS_COUNT_RD +MBOX3C1 CAS_COUNT_WR +MBOX4C0 CAS_COUNT_RD +MBOX4C1 CAS_COUNT_WR +MBOX5C0 CAS_COUNT_RD +MBOX5C1 CAS_COUNT_WR + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Energy [J] PWR0 +Power [W] PWR0/time +Energy DRAM [J] PWR3 +Power DRAM [W] PWR3/time +DP [MFLOP/s] 1.0E-06*(PMC0*2.0+PMC1+PMC2*4.0+PMC3*8.0)/time +AVX DP [MFLOP/s] 1.0E-06*(PMC2*4.0+PMC3*8.0)/time +Packed [MUOPS/s] 1.0E-06*(PMC0+PMC2+PMC3)/time +Scalar [MUOPS/s] 1.0E-06*PMC1/time +Memory read bandwidth [MBytes/s] 1.0E-06*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0)*64.0/time +Memory read data volume [GBytes] 1.0E-09*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0)*64.0 +Memory write bandwidth [MBytes/s] 1.0E-06*(MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1)*64.0/time +Memory write data volume [GBytes] 1.0E-09*(MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1)*64.0 +Memory bandwidth [MBytes/s] 1.0E-06*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1)*64.0/time +Memory data volume [GBytes] 1.0E-09*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1)*64.0 +Operational intensity (PMC0*2.0+PMC1+PMC2*4.0+PMC3*8.0)/((MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1)*64.0) + +LONG +Formulas: +Power [W] = PWR_PKG_ENERGY/runtime +Power DRAM [W] = PWR_DRAM_ENERGY/runtime +DP [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_128B_PACKED_DOUBLE*2+FP_ARITH_INST_RETIRED_SCALAR_DOUBLE+FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE*4+FP_ARITH_INST_RETIRED_512B_PACKED_DOUBLE*8)/runtime +AVX DP [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE*4+FP_ARITH_INST_RETIRED_512B_PACKED_DOUBLE*8)/runtime +Packed [MUOPS/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_128B_PACKED_DOUBLE+FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE+FP_ARITH_INST_RETIRED_512B_PACKED_DOUBLE)/runtime +Scalar [MUOPS/s] = 1.0E-06*FP_ARITH_INST_RETIRED_SCALAR_DOUBLE/runtime +Memory read bandwidth [MBytes/s] = 1.0E-06*(SUM(CAS_COUNT_RD))*64.0/runtime +Memory read data volume [GBytes] = 1.0E-09*(SUM(CAS_COUNT_RD))*64.0 +Memory write bandwidth [MBytes/s] = 1.0E-06*(SUM(CAS_COUNT_WR))*64.0/runtime +Memory write data volume [GBytes] = 1.0E-09*(SUM(CAS_COUNT_WR))*64.0 +Memory bandwidth [MBytes/s] = 1.0E-06*(SUM(CAS_COUNT_RD)+SUM(CAS_COUNT_WR))*64.0/runtime +Memory data volume [GBytes] = 1.0E-09*(SUM(CAS_COUNT_RD)+SUM(CAS_COUNT_WR))*64.0 +Operational intensity = (FP_ARITH_INST_RETIRED_128B_PACKED_DOUBLE*2+FP_ARITH_INST_RETIRED_SCALAR_DOUBLE+FP_ARITH_INST_RETIRED_256B_PACKED_DOUBLE*4+FP_ARITH_INST_RETIRED_512B_PACKED_DOUBLE*8)/(SUM(CAS_COUNT_RD)+SUM(CAS_COUNT_WR))*64.0) +-- +Profiling group to measure memory bandwidth drawn by all cores of a socket. +Since this group is based on Uncore events it is only possible to measure on +a per socket base. Also outputs total data volume transferred from main memory. +SSE scalar and packed double precision FLOP rates. Also reports on packed AVX +32b instructions. +The operational intensity is calculated using the FP values of the cores and the +memory data volume of the whole socket. The actual operational intensity for +multiple CPUs can be found in the statistics table in the Sum column. diff --git a/collectors/likwid/groups/skylakeX/MEM_SP.txt b/collectors/likwid/groups/skylakeX/MEM_SP.txt new file mode 100644 index 0000000..5720938 --- /dev/null +++ b/collectors/likwid/groups/skylakeX/MEM_SP.txt @@ -0,0 +1,70 @@ +SHORT Overview of arithmetic and main memory performance + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PWR0 PWR_PKG_ENERGY +PWR3 PWR_DRAM_ENERGY +PMC0 FP_ARITH_INST_RETIRED_128B_PACKED_SINGLE +PMC1 FP_ARITH_INST_RETIRED_SCALAR_SINGLE +PMC2 FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE +PMC3 FP_ARITH_INST_RETIRED_512B_PACKED_SINGLE +MBOX0C0 CAS_COUNT_RD +MBOX0C1 CAS_COUNT_WR +MBOX1C0 CAS_COUNT_RD +MBOX1C1 CAS_COUNT_WR +MBOX2C0 CAS_COUNT_RD +MBOX2C1 CAS_COUNT_WR +MBOX3C0 CAS_COUNT_RD +MBOX3C1 CAS_COUNT_WR +MBOX4C0 CAS_COUNT_RD +MBOX4C1 CAS_COUNT_WR +MBOX5C0 CAS_COUNT_RD +MBOX5C1 CAS_COUNT_WR + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Energy [J] PWR0 +Power [W] PWR0/time +Energy DRAM [J] PWR3 +Power DRAM [W] PWR3/time +SP [MFLOP/s] 1.0E-06*(PMC0*4.0+PMC1+PMC2*8.0+PMC3*16.0)/time +AVX SP [MFLOP/s] 1.0E-06*(PMC2*8.0+PMC3*16.0)/time +Packed [MUOPS/s] 1.0E-06*(PMC0+PMC2+PMC3)/time +Scalar [MUOPS/s] 1.0E-06*PMC1/time +Memory read bandwidth [MBytes/s] 1.0E-06*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0)*64.0/time +Memory read data volume [GBytes] 1.0E-09*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0)*64.0 +Memory write bandwidth [MBytes/s] 1.0E-06*(MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1)*64.0/time +Memory write data volume [GBytes] 1.0E-09*(MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1)*64.0 +Memory bandwidth [MBytes/s] 1.0E-06*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1)*64.0/time +Memory data volume [GBytes] 1.0E-09*(MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1)*64.0 +Operational intensity (PMC0*4.0+PMC1+PMC2*8.0+PMC3*16.0)/((MBOX0C0+MBOX1C0+MBOX2C0+MBOX3C0+MBOX4C0+MBOX5C0+MBOX0C1+MBOX1C1+MBOX2C1+MBOX3C1+MBOX4C1+MBOX5C1)*64.0) + +LONG +Formulas: +Power [W] = PWR_PKG_ENERGY/runtime +Power DRAM [W] = PWR_DRAM_ENERGY/runtime +SP [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_128B_PACKED_SINGLE*4+FP_ARITH_INST_RETIRED_SCALAR_SINGLE+FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE*8+FP_ARITH_INST_RETIRED_512B_PACKED_SINGLE*16)/runtime +AVX SP [MFLOP/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE*8+FP_ARITH_INST_RETIRED_512B_PACKED_SINGLE*16)/runtime +Packed [MUOPS/s] = 1.0E-06*(FP_ARITH_INST_RETIRED_128B_PACKED_SINGLE+FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE+FP_ARITH_INST_RETIRED_512B_PACKED_SINGLE)/runtime +Scalar [MUOPS/s] = 1.0E-06*FP_ARITH_INST_RETIRED_SCALAR_SINGLE/runtime +Memory read bandwidth [MBytes/s] = 1.0E-06*(SUM(CAS_COUNT_RD))*64.0/runtime +Memory read data volume [GBytes] = 1.0E-09*(SUM(CAS_COUNT_RD))*64.0 +Memory write bandwidth [MBytes/s] = 1.0E-06*(SUM(CAS_COUNT_WR))*64.0/runtime +Memory write data volume [GBytes] = 1.0E-09*(SUM(CAS_COUNT_WR))*64.0 +Memory bandwidth [MBytes/s] = 1.0E-06*(SUM(CAS_COUNT_RD)+SUM(CAS_COUNT_WR))*64.0/runtime +Memory data volume [GBytes] = 1.0E-09*(SUM(CAS_COUNT_RD)+SUM(CAS_COUNT_WR))*64.0 +Operational intensity = (FP_ARITH_INST_RETIRED_128B_PACKED_SINGLE*4+FP_ARITH_INST_RETIRED_SCALAR_SINGLE+FP_ARITH_INST_RETIRED_256B_PACKED_SINGLE*8+FP_ARITH_INST_RETIRED_512B_PACKED_SINGLE*16)/(SUM(CAS_COUNT_RD)+SUM(CAS_COUNT_WR))*64.0) +-- +Profiling group to measure memory bandwidth drawn by all cores of a socket. +Since this group is based on Uncore events it is only possible to measure on +a per socket base. Also outputs total data volume transferred from main memory. +SSE scalar and packed single precision FLOP rates. Also reports on packed AVX +32b instructions. +The operational intensity is calculated using the FP values of the cores and the +memory data volume of the whole socket. The actual operational intensity for +multiple CPUs can be found in the statistics table in the Sum column. diff --git a/collectors/likwid/groups/skylakeX/TLB_DATA.txt b/collectors/likwid/groups/skylakeX/TLB_DATA.txt new file mode 100644 index 0000000..10ee5e1 --- /dev/null +++ b/collectors/likwid/groups/skylakeX/TLB_DATA.txt @@ -0,0 +1,35 @@ +SHORT L2 data TLB miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 DTLB_LOAD_MISSES_CAUSES_A_WALK +PMC1 DTLB_STORE_MISSES_CAUSES_A_WALK +PMC2 DTLB_LOAD_MISSES_WALK_ACTIVE +PMC3 DTLB_STORE_MISSES_WALK_ACTIVE + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L1 DTLB load misses PMC0 +L1 DTLB load miss rate PMC0/FIXC0 +L1 DTLB load miss duration [Cyc] PMC2/PMC0 +L1 DTLB store misses PMC1 +L1 DTLB store miss rate PMC1/FIXC0 +L1 DTLB store miss duration [Cyc] PMC3/PMC1 + +LONG +Formulas: +L1 DTLB load misses = DTLB_LOAD_MISSES_CAUSES_A_WALK +L1 DTLB load miss rate = DTLB_LOAD_MISSES_CAUSES_A_WALK / INSTR_RETIRED_ANY +L1 DTLB load miss duration [Cyc] = DTLB_LOAD_MISSES_WALK_ACTIVE / DTLB_LOAD_MISSES_CAUSES_A_WALK +L1 DTLB store misses = DTLB_STORE_MISSES_CAUSES_A_WALK +L1 DTLB store miss rate = DTLB_STORE_MISSES_CAUSES_A_WALK / INSTR_RETIRED_ANY +L1 DTLB store miss duration [Cyc] = DTLB_STORE_MISSES_WALK_ACTIVE / DTLB_STORE_MISSES_CAUSES_A_WALK +- +The DTLB load and store miss rates gives a measure how often a TLB miss occurred +per instruction. The duration measures the time in cycles how long a walk did take. + diff --git a/collectors/likwid/groups/skylakeX/TLB_INSTR.txt b/collectors/likwid/groups/skylakeX/TLB_INSTR.txt new file mode 100644 index 0000000..9bc65a7 --- /dev/null +++ b/collectors/likwid/groups/skylakeX/TLB_INSTR.txt @@ -0,0 +1,28 @@ +SHORT L1 Instruction TLB miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 ITLB_MISSES_CAUSES_A_WALK +PMC1 ITLB_MISSES_WALK_ACTIVE + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L1 ITLB misses PMC0 +L1 ITLB miss rate PMC0/FIXC0 +L1 ITLB miss duration [Cyc] PMC1/PMC0 + + +LONG +Formulas: +L1 ITLB misses = ITLB_MISSES_CAUSES_A_WALK +L1 ITLB miss rate = ITLB_MISSES_CAUSES_A_WALK / INSTR_RETIRED_ANY +L1 ITLB miss duration [Cyc] = ITLB_MISSES_WALK_ACTIVE / ITLB_MISSES_CAUSES_A_WALK +- +The ITLB miss rates gives a measure how often a TLB miss occurred +per instruction. The duration measures the time in cycles how long a walk did take. + diff --git a/collectors/likwid/groups/skylakeX/TMA.txt b/collectors/likwid/groups/skylakeX/TMA.txt new file mode 100644 index 0000000..afb4126 --- /dev/null +++ b/collectors/likwid/groups/skylakeX/TMA.txt @@ -0,0 +1,48 @@ +SHORT Top down cycle allocation + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 UOPS_ISSUED_ANY +PMC1 UOPS_RETIRED_RETIRE_SLOTS +PMC2 IDQ_UOPS_NOT_DELIVERED_CORE +PMC3 INT_MISC_RECOVERY_CYCLES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +IPC FIXC0/FIXC1 +Total Slots 4*FIXC1 +Slots Retired PMC1 +Fetch Bubbles PMC2 +Recovery Bubbles 4*PMC3 +Front End [%] PMC2/(4*FIXC1)*100 +Speculation [%] (PMC0-PMC1+(4*PMC3))/(4*FIXC1)*100 +Retiring [%] PMC1/(4*FIXC1)*100 +Back End [%] (1-((PMC2+PMC0+(4*PMC3))/(4*FIXC1)))*100 + +LONG +Formulas: +Total Slots = 4*CPU_CLK_UNHALTED_CORE +Slots Retired = UOPS_RETIRED_RETIRE_SLOTS +Fetch Bubbles = IDQ_UOPS_NOT_DELIVERED_CORE +Recovery Bubbles = 4*INT_MISC_RECOVERY_CYCLES +Front End [%] = IDQ_UOPS_NOT_DELIVERED_CORE/(4*CPU_CLK_UNHALTED_CORE)*100 +Speculation [%] = (UOPS_ISSUED_ANY-UOPS_RETIRED_RETIRE_SLOTS+(4*INT_MISC_RECOVERY_CYCLES))/(4*CPU_CLK_UNHALTED_CORE)*100 +Retiring [%] = UOPS_RETIRED_RETIRE_SLOTS/(4*CPU_CLK_UNHALTED_CORE)*100 +Back End [%] = (1-((IDQ_UOPS_NOT_DELIVERED_CORE+UOPS_ISSUED_ANY+(4*INT_MISC_RECOVERY_CYCLES))/(4*CPU_CLK_UNHALTED_CORE)))*100 +-- +This performance group measures cycles to determine percentage of time spent in +front end, back end, retiring and speculation. These metrics are published and +verified by Intel. Further information: +Webpage describing Top-Down Method and its usage in Intel vTune: +https://software.intel.com/en-us/vtune-amplifier-help-tuning-applications-using-a-top-down-microarchitecture-analysis-method +Paper by Yasin Ahmad: +https://sites.google.com/site/analysismethods/yasin-pubs/TopDown-Yasin-ISPASS14.pdf?attredirects=0 +Slides by Yasin Ahmad: +http://www.cs.technion.ac.il/~erangi/TMA_using_Linux_perf__Ahmad_Yasin.pdf +The performance group was originally published here: +http://perf.mvermeulen.com/2018/04/14/top-down-performance-counter-analysis-part-1-likwid/ diff --git a/collectors/likwid/groups/skylakeX/UOPS_EXEC.txt b/collectors/likwid/groups/skylakeX/UOPS_EXEC.txt new file mode 100644 index 0000000..7042df7 --- /dev/null +++ b/collectors/likwid/groups/skylakeX/UOPS_EXEC.txt @@ -0,0 +1,31 @@ +SHORT UOPs execution + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 UOPS_EXECUTED_USED_CYCLES +PMC1 UOPS_EXECUTED_STALL_CYCLES +PMC2 CPU_CLOCK_UNHALTED_TOTAL_CYCLES +PMC3:EDGEDETECT UOPS_EXECUTED_STALL_CYCLES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Used cycles ratio [%] 100*PMC0/PMC2 +Unused cycles ratio [%] 100*PMC1/PMC2 +Avg stall duration [cycles] PMC1/PMC3:EDGEDETECT + + +LONG +Formulas: +Used cycles ratio [%] = 100*UOPS_EXECUTED_USED_CYCLES/CPU_CLK_UNHALTED_CORE +Unused cycles ratio [%] = 100*UOPS_EXECUTED_STALL_CYCLES/CPU_CLK_UNHALTED_CORE +Avg stall duration [cycles] = UOPS_EXECUTED_STALL_CYCLES/UOPS_EXECUTED_STALL_CYCLES:EDGEDETECT +- +This performance group returns the ratios of used and unused cycles regarding +the execution stage in the pipeline. Used cycles are all cycles where uOPs are +executed while unused cycles refer to pipeline stalls. Moreover, the group +calculates the average stall duration in cycles. diff --git a/collectors/likwid/groups/skylakeX/UOPS_ISSUE.txt b/collectors/likwid/groups/skylakeX/UOPS_ISSUE.txt new file mode 100644 index 0000000..9aac923 --- /dev/null +++ b/collectors/likwid/groups/skylakeX/UOPS_ISSUE.txt @@ -0,0 +1,31 @@ +SHORT UOPs issueing + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 UOPS_ISSUED_USED_CYCLES +PMC1 UOPS_ISSUED_STALL_CYCLES +PMC2 CPU_CLOCK_UNHALTED_TOTAL_CYCLES +PMC3:EDGEDETECT UOPS_ISSUED_STALL_CYCLES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Used cycles ratio [%] 100*PMC0/PMC2 +Unused cycles ratio [%] 100*PMC1/PMC2 +Avg stall duration [cycles] PMC1/PMC3:EDGEDETECT + + +LONG +Formulas: +Used cycles ratio [%] = 100*UOPS_ISSUED_USED_CYCLES/CPU_CLK_UNHALTED_CORE +Unused cycles ratio [%] = 100*UOPS_ISSUED_STALL_CYCLES/CPU_CLK_UNHALTED_CORE +Avg stall duration [cycles] = UOPS_ISSUED_STALL_CYCLES/UOPS_ISSUED_STALL_CYCLES:EDGEDETECT +- +This performance group returns the ratios of used and unused cycles regarding +the issue stage in the pipeline. Used cycles are all cycles where uOPs are +issued while unused cycles refer to pipeline stalls. Moreover, the group +calculates the average stall duration in cycles. diff --git a/collectors/likwid/groups/skylakeX/UOPS_RETIRE.txt b/collectors/likwid/groups/skylakeX/UOPS_RETIRE.txt new file mode 100644 index 0000000..0f37585 --- /dev/null +++ b/collectors/likwid/groups/skylakeX/UOPS_RETIRE.txt @@ -0,0 +1,31 @@ +SHORT UOPs retirement + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 UOPS_RETIRED_USED_CYCLES +PMC1 UOPS_RETIRED_STALL_CYCLES +PMC2 CPU_CLOCK_UNHALTED_TOTAL_CYCLES +PMC3:EDGEDETECT UOPS_RETIRED_STALL_CYCLES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Used cycles ratio [%] 100*PMC0/PMC2 +Unused cycles ratio [%] 100*PMC1/PMC2 +Avg stall duration [cycles] PMC1/PMC3:EDGEDETECT + + +LONG +Formulas: +Used cycles ratio [%] = 100*UOPS_RETIRED_USED_CYCLES/CPU_CLK_UNHALTED_CORE +Unused cycles ratio [%] = 100*UOPS_RETIRED_STALL_CYCLES/CPU_CLK_UNHALTED_CORE +Avg stall duration [cycles] = UOPS_RETIRED_STALL_CYCLES/UOPS_RETIRED_STALL_CYCLES:EDGEDETECT +- +This performance group returns the ratios of used and unused cycles regarding +the retirement stage in the pipeline (re-order buffer). Used cycles are all +cycles where uOPs are retired while unused cycles refer to pipeline stalls. +Moreover, the group calculates the average stall duration in cycles. diff --git a/collectors/likwid/groups/skylakeX/UPI.txt b/collectors/likwid/groups/skylakeX/UPI.txt new file mode 100644 index 0000000..2a4c44f --- /dev/null +++ b/collectors/likwid/groups/skylakeX/UPI.txt @@ -0,0 +1,42 @@ +SHORT UPI data traffic + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +SBOX0C0 TXL_FLITS_ALL_DATA +SBOX0C1 RXL_FLITS_ALL_DATA +SBOX1C0 TXL_FLITS_ALL_DATA +SBOX1C1 RXL_FLITS_ALL_DATA +SBOX2C0 TXL_FLITS_ALL_DATA +SBOX2C1 RXL_FLITS_ALL_DATA + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Received data bandwidth [MByte/s] 1.0E-06*((SBOX0C1+SBOX1C1+SBOX2C1)/9.0)*64.0/time +Received data volume [GByte] 1.0E-09*((SBOX0C1+SBOX1C1+SBOX2C1)/9.0)*64.0 +Sent data bandwidth [MByte/s] 1.0E-06*((SBOX0C0+SBOX1C0+SBOX2C0)/9.0)*64.0/time +Sent data volume [GByte] 1.0E-09*((SBOX0C0+SBOX1C0+SBOX2C0)/9.0)*64.0 +Total data bandwidth [MByte/s] 1.0E-06*((SBOX0C0+SBOX1C0+SBOX2C0+SBOX0C1+SBOX1C1+SBOX2C1)/9.0)*64.0/time +Total data volume [GByte] 1.0E-09*((SBOX0C0+SBOX1C0+SBOX2C0+SBOX0C1+SBOX1C1+SBOX2C1)/9.0)*64.0 + + +LONG +Formulas: +Received data bandwidth [MByte/s] = 1.0E-06*(SUM(RXL_FLITS_ALL_DATA)/9.0)*64.0/runtime +Received data volume [GByte] = 1.0E-09*(SUM(RXL_FLITS_ALL_DATA)/9.0)*64.0 +Sent data bandwidth [MByte/s] = 1.0E-06*(SUM(TXL_FLITS_ALL_DATA)/9.0)*64.0/time +Sent data volume [GByte] = 1.0E-09*(SUM(TXL_FLITS_ALL_DATA)/9.0)*64.0 +Total data bandwidth [MByte/s] = 1.0E-06*((SUM(RXL_FLITS_ALL_DATA)+SUM(TXL_FLITS_ALL_DATA))/9.0)*64.0/time +Total data volume [GByte] = 1.0E-09*((SUM(RXL_FLITS_ALL_DATA)+SUM(TXL_FLITS_ALL_DATA))/9.0)*64.0 +-- +This group measures the data traffic on the UPI (socket interconnect). The group +measures all filled data slots (9 slots per 64 Byte data transfer), that's why +the count needs to be divided by 9. These 9 data chunks are not transferred in +a single flit but there is one flit for the header and three flits for the data. +The metrics show higher values as expected because the events count also +different transfers which include data. diff --git a/collectors/likwid/groups/westmere/BRANCH.txt b/collectors/likwid/groups/westmere/BRANCH.txt new file mode 100644 index 0000000..b8d41b2 --- /dev/null +++ b/collectors/likwid/groups/westmere/BRANCH.txt @@ -0,0 +1,31 @@ +SHORT Branch prediction miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 BR_INST_RETIRED_ALL_BRANCHES +PMC1 BR_MISP_RETIRED_ALL_BRANCHES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Branch rate PMC0/FIXC0 +Branch misprediction rate PMC1/FIXC0 +Branch misprediction ratio PMC1/PMC0 +Instructions per branch FIXC0/PMC0 + +LONG +Formulas: +Branch rate = BR_INST_RETIRED_ALL_BRANCHES/INSTR_RETIRED_ANY +Branch misprediction rate = BR_MISP_RETIRED_ALL_BRANCHES/INSTR_RETIRED_ANY +Branch misprediction ratio = BR_MISP_RETIRED_ALL_BRANCHES/BR_INST_RETIRED_ALL_BRANCHES +Instructions per branch = INSTR_RETIRED_ANY/BR_INST_RETIRED_ALL_BRANCHES +- +The rates state how often on average a branch or a mispredicted branch occurred +per instruction retired in total. The branch misprediction ratio sets directly +into relation what ratio of all branch instruction where mispredicted. +Instructions per branch is 1/branch rate. + diff --git a/collectors/likwid/groups/westmere/CACHE.txt b/collectors/likwid/groups/westmere/CACHE.txt new file mode 100644 index 0000000..6a5e4fe --- /dev/null +++ b/collectors/likwid/groups/westmere/CACHE.txt @@ -0,0 +1,26 @@ +SHORT Data cache miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 L1D_REPL + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +data cache misses PMC0 +data cache miss rate PMC0/FIXC0 + +LONG +Formulas: +data cache misses = L1D_REPL +data cache miss rate = L1D_REPL / INSTR_RETIRED_ANY +- +This group measures the locality of your data accesses with regard to the +L1 cache. +The data cache miss rate gives a measure how often it was necessary to get +cache lines from higher levels of the memory hierarchy. + diff --git a/collectors/likwid/groups/westmere/CLOCK.txt b/collectors/likwid/groups/westmere/CLOCK.txt new file mode 100644 index 0000000..5f862a5 --- /dev/null +++ b/collectors/likwid/groups/westmere/CLOCK.txt @@ -0,0 +1,21 @@ +SHORT CPU clock information + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 + +LONG +Formulas: +Runtime (RDTSC) [s] = time +Runtime unhalted [s] = CPU_CLK_UNHALTED_CORE*inverseClock +Clock [MHz] = 1.E-06*(CPU_CLK_UNHALTED_CORE/CPU_CLK_UNHALTED_REF)/inverseClock +CPI = CPU_CLK_UNHALTED_CORE/INSTR_RETIRED_ANY +- +CPU clock information diff --git a/collectors/likwid/groups/westmere/DATA.txt b/collectors/likwid/groups/westmere/DATA.txt new file mode 100644 index 0000000..31bba51 --- /dev/null +++ b/collectors/likwid/groups/westmere/DATA.txt @@ -0,0 +1,22 @@ +SHORT Load to store ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 MEM_INST_RETIRED_LOADS +PMC1 MEM_INST_RETIRED_STORES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Load to store ratio PMC0/PMC1 + +LONG +Formulas: +Load to store ratio = MEM_INST_RETIRED_LOADS/MEM_INST_RETIRED_STORES +- +This is a simple metric to determine your load to store ratio. + diff --git a/collectors/likwid/groups/westmere/DIVIDE.txt b/collectors/likwid/groups/westmere/DIVIDE.txt new file mode 100644 index 0000000..2677a19 --- /dev/null +++ b/collectors/likwid/groups/westmere/DIVIDE.txt @@ -0,0 +1,24 @@ +SHORT Divide unit information + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 ARITH_NUM_DIV +PMC1 ARITH_CYCLES_DIV_BUSY + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Number of divide ops PMC0 +Avg. divide unit usage duration PMC1/PMC0 + +LONG +Formulas: +Number of divide ops = ARITH_NUM_DIV +Avg. divide unit usage duration = ARITH_CYCLES_DIV_BUSY/ARITH_NUM_DIV +- +This performance group measures the average latency of divide operations diff --git a/collectors/likwid/groups/westmere/FLOPS_DP.txt b/collectors/likwid/groups/westmere/FLOPS_DP.txt new file mode 100644 index 0000000..c5c8203 --- /dev/null +++ b/collectors/likwid/groups/westmere/FLOPS_DP.txt @@ -0,0 +1,35 @@ +SHORT Double Precision MFLOP/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 FP_COMP_OPS_EXE_SSE_FP_PACKED +PMC1 FP_COMP_OPS_EXE_SSE_FP_SCALAR +PMC2 FP_COMP_OPS_EXE_SSE_SINGLE_PRECISION +PMC3 FP_COMP_OPS_EXE_SSE_DOUBLE_PRECISION + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +DP [MFLOP/s] 1.0E-06*(PMC0*2.0+PMC1)/time +Packed [MUOPS/s] 1.0E-06*PMC0/time +Scalar [MUOPS/s] 1.0E-06*PMC1/time +SP [MUOPS/s] 1.0E-06*PMC2/time +DP [MUOPS/s] 1.0E-06*PMC3/time + +LONG +Formulas: +DP [MFLOP/s] = 1.0E-06*(FP_COMP_OPS_EXE_SSE_FP_PACKED*2+FP_COMP_OPS_EXE_SSE_FP_SCALAR)/runtime +Packed [MUOPS/s] = 1.0E-06*FP_COMP_OPS_EXE_SSE_FP_PACKED/runtime +Scalar [MUOPS/s] = 1.0E-06*FP_COMP_OPS_EXE_SSE_FP_SCALAR/runtime +SP [MUOPS/s] = 1.0E-06*FP_COMP_OPS_EXE_SSE_SINGLE_PRECISION/runtime +DP [MUOPS/s] = 1.0E-06*FP_COMP_OPS_EXE_SSE_DOUBLE_PRECISION/runtime +- +Westmere has no possibility to measure MFLOPs if mixed precision calculations are done. +Therefore both single as well as double precision are measured to ensure the correctness +of the measurements. You can check if your code was vectorized on the number of +FP_COMP_OPS_EXE_SSE_FP_PACKED versus the FP_COMP_OPS_EXE_SSE_FP_SCALAR. + diff --git a/collectors/likwid/groups/westmere/FLOPS_SP.txt b/collectors/likwid/groups/westmere/FLOPS_SP.txt new file mode 100644 index 0000000..933b058 --- /dev/null +++ b/collectors/likwid/groups/westmere/FLOPS_SP.txt @@ -0,0 +1,35 @@ +SHORT Single Precision MFLOP/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 FP_COMP_OPS_EXE_SSE_FP_PACKED +PMC1 FP_COMP_OPS_EXE_SSE_FP_SCALAR +PMC2 FP_COMP_OPS_EXE_SSE_SINGLE_PRECISION +PMC3 FP_COMP_OPS_EXE_SSE_DOUBLE_PRECISION + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +SP [MFLOP/s] 1.0E-06*(PMC0*4.0+PMC1)/time +Packed [MUOPS/s] 1.0E-06*PMC0/time +Scalar [MUOPS/s] 1.0E-06*PMC1/time +SP [MUOPS/s] 1.0E-06*PMC2/time +DP [MUOPS/s] 1.0E-06*PMC3/time + +LONG +Formulas: +SP [MFLOP/s] = 1.0E-06*(FP_COMP_OPS_EXE_SSE_FP_PACKED*4+FP_COMP_OPS_EXE_SSE_FP_SCALAR)/runtime +Packed [MUOPS/s] = 1.0E-06*FP_COMP_OPS_EXE_SSE_FP_PACKED/runtime +Scalar [MUOPS/s] = 1.0E-06*FP_COMP_OPS_EXE_SSE_FP_SCALAR/runtime +SP [MUOPS/s] = 1.0E-06*FP_COMP_OPS_EXE_SSE_SINGLE_PRECISION/runtime +DP [MUOPS/s] = 1.0E-06*FP_COMP_OPS_EXE_SSE_DOUBLE_PRECISION/runtime +- +Westmere has no possibility to measure MFLOPs if mixed precision calculations are done. +Therefore both single as well as double precision are measured to ensure the correctness +of the measurements. You can check if your code was vectorized on the number of +FP_COMP_OPS_EXE_SSE_FP_PACKED versus the FP_COMP_OPS_EXE_SSE_FP_SCALAR. + diff --git a/collectors/likwid/groups/westmere/FLOPS_X87.txt b/collectors/likwid/groups/westmere/FLOPS_X87.txt new file mode 100644 index 0000000..39cd8b4 --- /dev/null +++ b/collectors/likwid/groups/westmere/FLOPS_X87.txt @@ -0,0 +1,21 @@ +SHORT X87 MFLOP/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 INST_RETIRED_X87 + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +X87 [MFLOP/s] 1.0E-06*PMC0/time + +LONG +Formulas: +X87 [MFLOP/s] = 1.0E-06*INST_RETIRED_X87/runtime +- +Profiling group to measure X87 FLOP rate. + diff --git a/collectors/likwid/groups/westmere/ICACHE.txt b/collectors/likwid/groups/westmere/ICACHE.txt new file mode 100644 index 0000000..49943ff --- /dev/null +++ b/collectors/likwid/groups/westmere/ICACHE.txt @@ -0,0 +1,25 @@ +SHORT Instruction cache miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 L1I_READS +PMC1 L1I_MISSES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L1I request rate PMC0/FIXC0 +L1I miss rate PMC1/FIXC0 +L1I miss ratio PMC1/PMC0 + +LONG +Formulas: +L1I request rate = L1I_READS / INSTR_RETIRED_ANY +L1I miss rate = ICACHE_MISSES / INSTR_RETIRED_ANY +L1I miss ratio = ICACHE_MISSES / L1I_READS +- +This group measures some L1 instruction cache metrics. diff --git a/collectors/likwid/groups/westmere/L2.txt b/collectors/likwid/groups/westmere/L2.txt new file mode 100644 index 0000000..74f7d58 --- /dev/null +++ b/collectors/likwid/groups/westmere/L2.txt @@ -0,0 +1,38 @@ +SHORT L2 cache bandwidth in MBytes/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 L1D_REPL +PMC1 L1D_M_EVICT +PMC2 L1I_MISSES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L2D load bandwidth [MBytes/s] 1.0E-06*PMC0*64.0/time +L2D load data volume [GBytes] 1.0E-09*PMC0*64.0 +L2D evict bandwidth [MBytes/s] 1.0E-06*PMC1*64.0/time +L2D evict data volume [GBytes] 1.0E-09*PMC1*64.0 +L2 bandwidth [MBytes/s] 1.0E-06*(PMC0+PMC1+PMC2)*64.0/time +L2 data volume [GBytes] 1.0E-09*(PMC0+PMC1+PMC2)*64.0 + +LONG +Formulas: +L2D load bandwidth [MBytes/s] = 1.0E-06*L1D_REPL*64.0/time +L2D load data volume [GBytes] = 1.0E-09*L1D_REPL*64.0 +L2D evict bandwidth [MBytes/s] = 1.0E-06*L1D_M_EVICT*64.0/time +L2D evict data volume [GBytes] = 1.0E-09*L1D_M_EVICT*64.0 +L2 bandwidth [MBytes/s] = 1.0E-06*(L1D_REPL+L1D_M_EVICT+L1I_MISSES)*64/time +L2 data volume [GBytes] = 1.0E-09*(L1D_REPL+L1D_M_EVICT+L1I_MISSES)*64 +- +Profiling group to measure L2 cache bandwidth. The bandwidth is computed by the +number of cache line allocated in the L1 and the number of modified cache lines +evicted from the L1. The group also reports of data volume transferred between +L2 and L1 cache. Note that this bandwidth also includes data transfers due to a +write allocate load on a store miss in L1 and traffic caused by misses in the +L1 instruction cache. + diff --git a/collectors/likwid/groups/westmere/L2CACHE.txt b/collectors/likwid/groups/westmere/L2CACHE.txt new file mode 100644 index 0000000..343b263 --- /dev/null +++ b/collectors/likwid/groups/westmere/L2CACHE.txt @@ -0,0 +1,34 @@ +SHORT L2 cache miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 L2_RQSTS_REFERENCES +PMC1 L2_RQSTS_MISS + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L2 request rate PMC0/FIXC0 +L2 miss rate PMC1/FIXC0 +L2 miss ratio PMC1/PMC0 + +LONG +Formulas: +L2 request rate = L2_RQSTS_REFERENCES/INSTR_RETIRED_ANY +L2 miss rate = L2_RQSTS_MISS/INSTR_RETIRED_ANY +L2 miss ratio = L2_RQSTS_MISS/L2_RQSTS_REFERENCES +- +This group measures the locality of your data accesses with regard to the +L2 cache. L2 request rate tells you how data intensive your code is +or how many data accesses you have on average per instruction. +The L2 miss rate gives a measure how often it was necessary to get +cache lines from memory. And finally L2 miss ratio tells you how many of your +memory references required a cache line to be loaded from a higher level. +While the data cache miss rate might be given by your algorithm you should +try to get data cache miss ratio as low as possible by increasing your cache reuse. + + diff --git a/collectors/likwid/groups/westmere/L3.txt b/collectors/likwid/groups/westmere/L3.txt new file mode 100644 index 0000000..a1d95e3 --- /dev/null +++ b/collectors/likwid/groups/westmere/L3.txt @@ -0,0 +1,37 @@ +SHORT L3 cache bandwidth in MBytes/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 L2_RQSTS_MISS +PMC1 L2_LINES_OUT_DIRTY_ANY + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L3 load bandwidth [MBytes/s] 1.0E-06*PMC0*64.0/time +L3 load data volume [GBytes] 1.0E-09*PMC0*64.0 +L3 evict bandwidth [MBytes/s] 1.0E-06*(PMC1)*64.0/time +L3 evict data volume [GBytes] 1.0E-09*(PMC1)*64.0 +L3 bandwidth [MBytes/s] 1.0E-06*(PMC0+PMC1)*64.0/time +L3 data volume [GBytes] 1.0E-09*(PMC0+PMC1)*64.0 + +LONG +Formulas: +L3 load bandwidth [MBytes/s] = 1.0E-06*L2_RQSTS_MISS*64.0/time +L3 load data volume [GBytes] = 1.0E-09*L2_RQSTS_MISS*64.0 +L3 evict bandwidth [MBytes/s] = 1.0E-06*L2_LINES_OUT_DIRTY_ANY*64.0/time +L3 evict data volume [GBytes] = 1.0E-09*L2_LINES_OUT_DIRTY_ANY*64.0 +L3 bandwidth [MBytes/s] = 1.0E-06*(L2_RQSTS_MISS+L2_LINES_OUT_DIRTY_ANY)*64/time +L3 data volume [GBytes] = 1.0E-09*(L2_RQSTS_MISS+L2_LINES_OUT_DIRTY_ANY)*64 +- +Profiling group to measure L3 cache bandwidth. The bandwidth is computed by the +number of cache line allocated in the L2 and the number of modified cache lines +evicted from the L2. The group also reports total data volume between L3 and +the measured L2 cache. Note that this bandwidth also includes data transfers +due to a write allocate load on a store miss in L2. + diff --git a/collectors/likwid/groups/westmere/L3CACHE.txt b/collectors/likwid/groups/westmere/L3CACHE.txt new file mode 100644 index 0000000..58072c1 --- /dev/null +++ b/collectors/likwid/groups/westmere/L3CACHE.txt @@ -0,0 +1,34 @@ +SHORT L3 cache miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +UPMC0 UNC_L3_HITS_ANY +UPMC1 UNC_L3_MISS_ANY + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L3 request rate (UPMC0+UPMC1)/FIXC0 +L3 miss rate UPMC1/FIXC0 +L3 miss ratio UPMC1/(UPMC0+UPMC1) + +LONG +Formulas: +L3 request rate = (UNC_L3_HITS_ANY+UNC_L3_MISS_ANY)/INSTR_RETIRED_ANY +L3 miss rate = UNC_L3_MISS_ANY/INSTR_RETIRED_ANY +L3 miss ratio = UNC_L3_MISS_ANY/(UNC_L3_HITS_ANY+UNC_L3_MISS_ANY) +- +This group measures the locality of your data accesses with regard to the L3 +Cache. L3 request rate tells you how data intensive your code is or how many +data accesses you have on average per instruction. The L3 miss rate gives a +measure how often it was necessary to get cache lines from memory. And finally +L3 miss ratio tells you how many of your memory references required a cache line +to be loaded from a higher level. While the data cache miss rate might be given +by your algorithm you should try to get data cache miss ratio as low as +possible by increasing your cache reuse. + + diff --git a/collectors/likwid/groups/westmere/MEM.txt b/collectors/likwid/groups/westmere/MEM.txt new file mode 100644 index 0000000..b5165e1 --- /dev/null +++ b/collectors/likwid/groups/westmere/MEM.txt @@ -0,0 +1,50 @@ +SHORT Main memory bandwidth in MBytes/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +UPMC0 UNC_QMC_NORMAL_READS_ANY +UPMC1 UNC_QMC_WRITES_FULL_ANY +UPMC2 UNC_QHL_REQUESTS_REMOTE_READS +UPMC3 UNC_QHL_REQUESTS_REMOTE_WRITES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Memory read bandwidth [MBytes/s] 1.0E-06*UPMC0*64.0/time +Memory read data volume [GBytes] 1.0E-09*UPMC0*64.0 +Memory write bandwidth [MBytes/s] 1.0E-06*UPMC1*64.0/time +Memory write data volume [GBytes] 1.0E-09*UPMC1*64.0 +Memory bandwidth [MBytes/s] 1.0E-06*(UPMC0+UPMC1)*64.0/time +Memory data volume [GBytes] 1.0E-09*(UPMC0+UPMC1)*64.0 +Remote memory read bandwidth [MBytes/s] 1.0E-06*UPMC2*64.0/time +Remote memory read data volume [GBytes] 1.0E-09*UPMC2*64.0 +Remote memory write bandwidth [MBytes/s] 1.0E-06*UPMC3*64.0/time +Remote memory write data volume [GBytes] 1.0E-09*UPMC3*64.0 +Remote memory bandwidth [MBytes/s] 1.0E-06*(UPMC2+UPMC3)*64.0/time +Remote memory data volume [GBytes] 1.0E-09*(UPMC2+UPMC3)*64.0 + +LONG +Formulas: +Memory read bandwidth [MBytes/s] = 1.0E-06*UNC_QMC_NORMAL_READS_ANY*64.0/time +Memory read data volume [GBytes] = 1.0E-09*UNC_QMC_NORMAL_READS_ANY*64.0 +Memory write bandwidth [MBytes/s] = 1.0E-06*UNC_QMC_WRITES_FULL_ANY*64.0/time +Memory write data volume [GBytes] = 1.0E-09*UNC_QMC_WRITES_FULL_ANY*64.0 +Memory bandwidth [MBytes/s] = 1.0E-06*(UNC_QMC_NORMAL_READS_ANY+UNC_QMC_WRITES_FULL_ANY)*64.0/time +Memory data volume [GBytes] = 1.0E-09*(UNC_QMC_NORMAL_READS_ANY+UNC_QMC_WRITES_FULL_ANY)*64.0 +Remote memory read bandwidth [MBytes/s] = 1.0E-06*UNC_QHL_REQUESTS_REMOTE_READS*64.0/time +Remote memory read data volume [GBytes] = 1.0E-09*UNC_QHL_REQUESTS_REMOTE_READS*64.0 +Remote memory write bandwidth [MBytes/s] = 1.0E-06*UNC_QHL_REQUESTS_REMOTE_WRITES*64.0/time +Remote memory write data volume [GBytes] = 1.0E-09*UNC_QHL_REQUESTS_REMOTE_WRITES*64.0 +Remote memory bandwidth [MBytes/s] = 1.0E-06*(UNC_QHL_REQUESTS_REMOTE_READS+UNC_QHL_REQUESTS_REMOTE_WRITES)*64.0/time +Remote memory data volume [GBytes] = 1.0E-09*(UNC_QHL_REQUESTS_REMOTE_READS+UNC_QHL_REQUESTS_REMOTE_WRITES)*64.0 +- +Profiling group to measure memory bandwidth drawn by all cores of a socket. +This group will be measured by one core per socket. The remote read BW tells +you if cache lines are transferred between sockets, meaning that cores access +data owned by a remote NUMA domain. The group also reports total data volume +transferred from main memory. + diff --git a/collectors/likwid/groups/westmere/MEM_DP.txt b/collectors/likwid/groups/westmere/MEM_DP.txt new file mode 100644 index 0000000..64161dd --- /dev/null +++ b/collectors/likwid/groups/westmere/MEM_DP.txt @@ -0,0 +1,66 @@ +SHORT Main memory bandwidth in MBytes/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 FP_COMP_OPS_EXE_SSE_FP_PACKED +PMC1 FP_COMP_OPS_EXE_SSE_FP_SCALAR +PMC2 FP_COMP_OPS_EXE_SSE_SINGLE_PRECISION +PMC3 FP_COMP_OPS_EXE_SSE_DOUBLE_PRECISION +UPMC0 UNC_QMC_NORMAL_READS_ANY +UPMC1 UNC_QMC_WRITES_FULL_ANY +UPMC2 UNC_QHL_REQUESTS_REMOTE_READS +UPMC3 UNC_QHL_REQUESTS_REMOTE_WRITES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +DP [MFLOP/s] 1.0E-06*(PMC0*2.0+PMC1)/time +Packed [MUOPS/s] 1.0E-06*PMC0/time +Scalar [MUOPS/s] 1.0E-06*PMC1/time +SP [MUOPS/s] 1.0E-06*PMC2/time +DP [MUOPS/s] 1.0E-06*PMC3/time +Memory read bandwidth [MBytes/s] 1.0E-06*UPMC0*64.0/time +Memory read data volume [GBytes] 1.0E-09*UPMC0*64.0 +Memory write bandwidth [MBytes/s] 1.0E-06*UPMC1*64.0/time +Memory write data volume [GBytes] 1.0E-09*UPMC1*64.0 +Memory bandwidth [MBytes/s] 1.0E-06*(UPMC0+UPMC1)*64.0/time +Memory data volume [GBytes] 1.0E-09*(UPMC0+UPMC1)*64.0 +Remote memory read bandwidth [MBytes/s] 1.0E-06*UPMC2*64.0/time +Remote memory read data volume [GBytes] 1.0E-09*UPMC2*64.0 +Remote memory write bandwidth [MBytes/s] 1.0E-06*UPMC3*64.0/time +Remote memory write data volume [GBytes] 1.0E-09*UPMC3*64.0 +Remote memory bandwidth [MBytes/s] 1.0E-06*(UPMC2+UPMC3)*64.0/time +Remote memory data volume [GBytes] 1.0E-09*(UPMC2+UPMC3)*64.0 +Operational intensity (PMC0*2.0+PMC1)/((UPMC0+UPMC1)*64.0) + +LONG +Formulas: +DP [MFLOP/s] = 1.0E-06*(FP_COMP_OPS_EXE_SSE_FP_PACKED*2+FP_COMP_OPS_EXE_SSE_FP_SCALAR)/runtime +Packed [MUOPS/s] = 1.0E-06*FP_COMP_OPS_EXE_SSE_FP_PACKED/runtime +Scalar [MUOPS/s] = 1.0E-06*FP_COMP_OPS_EXE_SSE_FP_SCALAR/runtime +SP [MUOPS/s] = 1.0E-06*FP_COMP_OPS_EXE_SSE_SINGLE_PRECISION/runtime +DP [MUOPS/s] = 1.0E-06*FP_COMP_OPS_EXE_SSE_DOUBLE_PRECISION/runtime +Memory read bandwidth [MBytes/s] = 1.0E-06*UNC_QMC_NORMAL_READS_ANY*64.0/time +Memory read data volume [GBytes] = 1.0E-09*UNC_QMC_NORMAL_READS_ANY*64.0 +Memory write bandwidth [MBytes/s] = 1.0E-06*UNC_QMC_WRITES_FULL_ANY*64.0/time +Memory write data volume [GBytes] = 1.0E-09*UNC_QMC_WRITES_FULL_ANY*64.0 +Memory bandwidth [MBytes/s] = 1.0E-06*(UNC_QMC_NORMAL_READS_ANY+UNC_QMC_WRITES_FULL_ANY)*64.0/time +Memory data volume [GBytes] = 1.0E-09*(UNC_QMC_NORMAL_READS_ANY+UNC_QMC_WRITES_FULL_ANY)*64.0 +Remote memory read bandwidth [MBytes/s] = 1.0E-06*UNC_QHL_REQUESTS_REMOTE_READS*64.0/time +Remote memory read data volume [GBytes] = 1.0E-09*UNC_QHL_REQUESTS_REMOTE_READS*64.0 +Remote memory write bandwidth [MBytes/s] = 1.0E-06*UNC_QHL_REQUESTS_REMOTE_WRITES*64.0/time +Remote memory write data volume [GBytes] = 1.0E-09*UNC_QHL_REQUESTS_REMOTE_WRITES*64.0 +Remote memory bandwidth [MBytes/s] = 1.0E-06*(UNC_QHL_REQUESTS_REMOTE_READS+UNC_QHL_REQUESTS_REMOTE_WRITES)*64.0/time +Remote memory data volume [GBytes] = 1.0E-09*(UNC_QHL_REQUESTS_REMOTE_READS+UNC_QHL_REQUESTS_REMOTE_WRITES)*64.0 +Operational intensity = (FP_COMP_OPS_EXE_SSE_FP_PACKED*2+FP_COMP_OPS_EXE_SSE_FP_SCALAR)/((UNC_QMC_NORMAL_READS_ANY+UNC_QMC_WRITES_FULL_ANY)*64.0) +- +Profiling group to measure memory bandwidth drawn by all cores of a socket. +This group will be measured by one core per socket. The remote read BW tells +you if cache lines are transferred between sockets, meaning that cores access +data owned by a remote NUMA domain. The group also reports total data volume +transferred from main memory. + diff --git a/collectors/likwid/groups/westmere/MEM_SP.txt b/collectors/likwid/groups/westmere/MEM_SP.txt new file mode 100644 index 0000000..812c7fa --- /dev/null +++ b/collectors/likwid/groups/westmere/MEM_SP.txt @@ -0,0 +1,66 @@ +SHORT Main memory bandwidth in MBytes/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 FP_COMP_OPS_EXE_SSE_FP_PACKED +PMC1 FP_COMP_OPS_EXE_SSE_FP_SCALAR +PMC2 FP_COMP_OPS_EXE_SSE_SINGLE_PRECISION +PMC3 FP_COMP_OPS_EXE_SSE_DOUBLE_PRECISION +UPMC0 UNC_QMC_NORMAL_READS_ANY +UPMC1 UNC_QMC_WRITES_FULL_ANY +UPMC2 UNC_QHL_REQUESTS_REMOTE_READS +UPMC3 UNC_QHL_REQUESTS_REMOTE_WRITES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +SP [MFLOP/s] 1.0E-06*(PMC0*4.0+PMC1)/time +Packed [MUOPS/s] 1.0E-06*PMC0/time +Scalar [MUOPS/s] 1.0E-06*PMC1/time +SP [MUOPS/s] 1.0E-06*PMC2/time +DP [MUOPS/s] 1.0E-06*PMC3/time +Memory read bandwidth [MBytes/s] 1.0E-06*UPMC0*64.0/time +Memory read data volume [GBytes] 1.0E-09*UPMC0*64.0 +Memory write bandwidth [MBytes/s] 1.0E-06*UPMC1*64.0/time +Memory write data volume [GBytes] 1.0E-09*UPMC1*64.0 +Memory bandwidth [MBytes/s] 1.0E-06*(UPMC0+UPMC1)*64.0/time +Memory data volume [GBytes] 1.0E-09*(UPMC0+UPMC1)*64.0 +Remote memory read bandwidth [MBytes/s] 1.0E-06*UPMC2*64.0/time +Remote memory read data volume [GBytes] 1.0E-09*UPMC2*64.0 +Remote memory write bandwidth [MBytes/s] 1.0E-06*UPMC3*64.0/time +Remote memory write data volume [GBytes] 1.0E-09*UPMC3*64.0 +Remote memory bandwidth [MBytes/s] 1.0E-06*(UPMC2+UPMC3)*64.0/time +Remote memory data volume [GBytes] 1.0E-09*(UPMC2+UPMC3)*64.0 +Operational intensity (PMC0*4.0+PMC1)/((UPMC0+UPMC1)*64.0) + +LONG +Formulas: +SP [MFLOP/s] = 1.0E-06*(FP_COMP_OPS_EXE_SSE_FP_PACKED*4+FP_COMP_OPS_EXE_SSE_FP_SCALAR)/runtime +Packed [MUOPS/s] = 1.0E-06*FP_COMP_OPS_EXE_SSE_FP_PACKED/runtime +Scalar [MUOPS/s] = 1.0E-06*FP_COMP_OPS_EXE_SSE_FP_SCALAR/runtime +SP [MUOPS/s] = 1.0E-06*FP_COMP_OPS_EXE_SSE_SINGLE_PRECISION/runtime +DP [MUOPS/s] = 1.0E-06*FP_COMP_OPS_EXE_SSE_DOUBLE_PRECISION/runtime +Memory read bandwidth [MBytes/s] = 1.0E-06*UNC_QMC_NORMAL_READS_ANY*64.0/time +Memory read data volume [GBytes] = 1.0E-09*UNC_QMC_NORMAL_READS_ANY*64.0 +Memory write bandwidth [MBytes/s] = 1.0E-06*UNC_QMC_WRITES_FULL_ANY*64.0/time +Memory write data volume [GBytes] = 1.0E-09*UNC_QMC_WRITES_FULL_ANY*64.0 +Memory bandwidth [MBytes/s] = 1.0E-06*(UNC_QMC_NORMAL_READS_ANY+UNC_QMC_WRITES_FULL_ANY)*64.0/time +Memory data volume [GBytes] = 1.0E-09*(UNC_QMC_NORMAL_READS_ANY+UNC_QMC_WRITES_FULL_ANY)*64.0 +Remote memory read bandwidth [MBytes/s] = 1.0E-06*UNC_QHL_REQUESTS_REMOTE_READS*64.0/time +Remote memory read data volume [GBytes] = 1.0E-09*UNC_QHL_REQUESTS_REMOTE_READS*64.0 +Remote memory write bandwidth [MBytes/s] = 1.0E-06*UNC_QHL_REQUESTS_REMOTE_WRITES*64.0/time +Remote memory write data volume [GBytes] = 1.0E-09*UNC_QHL_REQUESTS_REMOTE_WRITES*64.0 +Remote memory bandwidth [MBytes/s] = 1.0E-06*(UNC_QHL_REQUESTS_REMOTE_READS+UNC_QHL_REQUESTS_REMOTE_WRITES)*64.0/time +Remote memory data volume [GBytes] = 1.0E-09*(UNC_QHL_REQUESTS_REMOTE_READS+UNC_QHL_REQUESTS_REMOTE_WRITES)*64.0 +Operational intensity = (FP_COMP_OPS_EXE_SSE_FP_PACKED*4+FP_COMP_OPS_EXE_SSE_FP_SCALAR)/((UNC_QMC_NORMAL_READS_ANY+UNC_QMC_WRITES_FULL_ANY)*64.0) +- +Profiling group to measure memory bandwidth drawn by all cores of a socket. +This group will be measured by one core per socket. The remote read BW tells +you if cache lines are transferred between sockets, meaning that cores access +data owned by a remote NUMA domain. The group also reports total data volume +transferred from main memory. + diff --git a/collectors/likwid/groups/westmere/TLB_DATA.txt b/collectors/likwid/groups/westmere/TLB_DATA.txt new file mode 100644 index 0000000..d256b8c --- /dev/null +++ b/collectors/likwid/groups/westmere/TLB_DATA.txt @@ -0,0 +1,35 @@ +SHORT L2 data TLB miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 DTLB_LOAD_MISSES_ANY +PMC1 DTLB_MISSES_ANY +PMC2 DTLB_LOAD_MISSES_WALK_CYCLES +PMC3 DTLB_MISSES_WALK_CYCLES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L1 DTLB load misses PMC0 +L1 DTLB load miss rate PMC0/FIXC0 +L1 DTLB load miss duration [Cyc] PMC2/PMC0 +L1 DTLB store misses (PMC1-PMC0) +L1 DTLB store miss rate (PMC1-PMC0)/FIXC0 +L1 DTLB store miss duration [Cyc] (PMC3-PMC2)/(PMC1-PMC0) + +LONG +Formulas: +L1 DTLB load misses = DTLB_LOAD_MISSES_ANY +L1 DTLB load miss rate = DTLB_LOAD_MISSES_ANY / INSTR_RETIRED_ANY +L1 DTLB load miss duration [Cyc] = DTLB_LOAD_MISSES_WALK_CYCLES / DTLB_LOAD_MISSES_ANY +L1 DTLB store misses = DTLB_MISSES_ANY-DTLB_LOAD_MISSES_ANY +L1 DTLB store miss rate = (DTLB_MISSES_ANY-DTLB_LOAD_MISSES_ANY) / INSTR_RETIRED_ANY +L1 DTLB store miss duration [Cyc] = (DTLB_MISSES_WALK_CYCLES-DTLB_LOAD_MISSES_WALK_CYCLES) / (DTLB_MISSES_ANY-DTLB_LOAD_MISSES_ANY) +- +The DTLB miss rate gives a measure how often a TLB miss occurred +per instruction. The store miss calculations are done using ALL-LOADS TLB walks. + diff --git a/collectors/likwid/groups/westmere/TLB_INSTR.txt b/collectors/likwid/groups/westmere/TLB_INSTR.txt new file mode 100644 index 0000000..2f0f90c --- /dev/null +++ b/collectors/likwid/groups/westmere/TLB_INSTR.txt @@ -0,0 +1,27 @@ +SHORT L1 Instruction TLB miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 ITLB_MISSES_ANY +PMC1 ITLB_MISSES_WALK_CYCLES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L1 ITLB misses PMC0 +L1 ITLB miss rate PMC0/FIXC0 +L1 ITLB miss duration [Cyc] PMC1/PMC0 + +LONG +Formulas: +L1 ITLB misses = ITLB_MISSES_ANY +L1 ITLB miss rate = ITLB_MISSES_ANY / INSTR_RETIRED_ANY +L1 ITLB miss duration [Cyc] = ITLB_MISSES_WALK_CYCLES / ITLB_MISSES_ANY +- +The ITLB miss rates gives a measure how often a TLB miss occurred +per instruction. The duration measures the time in cycles how long a walk did take. + diff --git a/collectors/likwid/groups/westmere/UOPS.txt b/collectors/likwid/groups/westmere/UOPS.txt new file mode 100644 index 0000000..b2446aa --- /dev/null +++ b/collectors/likwid/groups/westmere/UOPS.txt @@ -0,0 +1,35 @@ +SHORT UOPs execution info + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 UOPS_ISSUED_ANY +PMC1 UOPS_EXECUTED_THREAD +PMC2 UOPS_RETIRED_ANY +PMC3 UOPS_ISSUED_FUSED + + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Issued UOPs PMC0 +Merged UOPs PMC3 +Executed UOPs PMC1 +Retired UOPs PMC2 + +LONG +Formulas: +Issued UOPs = UOPS_ISSUED_ANY +Merged UOPs = UOPS_ISSUED_FUSED +Executed UOPs = UOPS_EXECUTED_THREAD +Retired UOPs = UOPS_RETIRED_ANY +- +This group returns information about the instruction pipeline. It measures the +issued, executed and retired uOPs and returns the number of uOPs which were issued +but not executed as well as the number of uOPs which were executed but never retired. +The executed but not retired uOPs commonly come from speculatively executed branches. + diff --git a/collectors/likwid/groups/westmere/VIEW.txt b/collectors/likwid/groups/westmere/VIEW.txt new file mode 100644 index 0000000..38d907c --- /dev/null +++ b/collectors/likwid/groups/westmere/VIEW.txt @@ -0,0 +1,50 @@ +SHORT Overview of arithmetic and memory performance + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 FP_COMP_OPS_EXE_SSE_FP_PACKED +PMC1 FP_COMP_OPS_EXE_SSE_FP_SCALAR +PMC2 FP_COMP_OPS_EXE_SSE_SINGLE_PRECISION +PMC3 FP_COMP_OPS_EXE_SSE_DOUBLE_PRECISION +UPMC0 UNC_QMC_NORMAL_READS_ANY +UPMC1 UNC_QMC_WRITES_FULL_ANY +UPMC2 UNC_QHL_REQUESTS_REMOTE_READS +UPMC3 UNC_QHL_REQUESTS_LOCAL_READS +UPMC4 UNC_QHL_REQUESTS_REMOTE_WRITES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +DP [MFLOP/s] (DP assumed) 1.0E-06*(PMC0*2.0+PMC1)/time +SP [MFLOP/s] (SP assumed) 1.0E-06*(PMC0*4.0+PMC1)/time +Packed [MUOPS/s] 1.0E-06*PMC0/time +Scalar [MUOPS/s] 1.0E-06*PMC1/time +SP [MUOPS/s] 1.0E-06*PMC2/time +DP [MUOPS/s] 1.0E-06*PMC3/time +Memory bandwidth [MBytes/s] 1.0E-06*(UPMC0+UPMC1)*64/time +Memory data volume [GBytes] 1.0E-09*(UPMC0+UPMC1)*64 +Remote Read BW [MBytes/s] 1.0E-06*(UPMC2)*64/time +Remote Write BW [MBytes/s] 1.0E-06*(UPMC4)*64/time +Remote BW [MBytes/s] 1.0E-06*(UPMC2+UPMC4)*64/time + +LONG +Formulas: +DP [MFLOP/s] = (FP_COMP_OPS_EXE_SSE_FP_PACKED*2 + FP_COMP_OPS_EXE_SSE_FP_SCALAR)/ runtime +SP [MFLOP/s] = (FP_COMP_OPS_EXE_SSE_FP_PACKED*4 + FP_COMP_OPS_EXE_SSE_FP_SCALAR)/ runtime +Packed [MUOPS/s] = 1.0E-06*FP_COMP_OPS_EXE_SSE_FP_PACKED/time +Scalar [MUOPS/s] = 1.0E-06*FP_COMP_OPS_EXE_SSE_FP_SCALAR/time +SP [MUOPS/s] = 1.0E-06*FP_COMP_OPS_EXE_SSE_SINGLE_PRECISION/time +DP [MUOPS/s] = 1.0E-06*FP_COMP_OPS_EXE_SSE_DOUBLE_PRECISION/time +Memory bandwidth [MBytes/s] = 1.0E-06*(UNC_QMC_NORMAL_READS_ANY+UNC_QMC_WRITES_FULL_ANY)*64/time +Memory data volume [GBytes] = 1.0E-09*(UNC_QMC_NORMAL_READS_ANY+UNC_QMC_WRITES_FULL_ANY)*64 +Remote Read BW [MBytes/s] = 1.0E-06*(UNC_QHL_REQUESTS_REMOTE_READS)*64/time +Remote Write BW [MBytes/s] = 1.0E-06*(UNC_QHL_REQUESTS_REMOTE_WRITES)*64/time +Remote BW [MBytes/s] = 1.0E-06*(UNC_QHL_REQUESTS_REMOTE_READS+UNC_QHL_REQUESTS_REMOTE_WRITES)*64/time +- +This is a overview group using the capabilities of Westmere to measure multiple events at +the same time. + diff --git a/collectors/likwid/groups/westmereEX/BRANCH.txt b/collectors/likwid/groups/westmereEX/BRANCH.txt new file mode 100644 index 0000000..b8d41b2 --- /dev/null +++ b/collectors/likwid/groups/westmereEX/BRANCH.txt @@ -0,0 +1,31 @@ +SHORT Branch prediction miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 BR_INST_RETIRED_ALL_BRANCHES +PMC1 BR_MISP_RETIRED_ALL_BRANCHES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Branch rate PMC0/FIXC0 +Branch misprediction rate PMC1/FIXC0 +Branch misprediction ratio PMC1/PMC0 +Instructions per branch FIXC0/PMC0 + +LONG +Formulas: +Branch rate = BR_INST_RETIRED_ALL_BRANCHES/INSTR_RETIRED_ANY +Branch misprediction rate = BR_MISP_RETIRED_ALL_BRANCHES/INSTR_RETIRED_ANY +Branch misprediction ratio = BR_MISP_RETIRED_ALL_BRANCHES/BR_INST_RETIRED_ALL_BRANCHES +Instructions per branch = INSTR_RETIRED_ANY/BR_INST_RETIRED_ALL_BRANCHES +- +The rates state how often on average a branch or a mispredicted branch occurred +per instruction retired in total. The branch misprediction ratio sets directly +into relation what ratio of all branch instruction where mispredicted. +Instructions per branch is 1/branch rate. + diff --git a/collectors/likwid/groups/westmereEX/CACHE.txt b/collectors/likwid/groups/westmereEX/CACHE.txt new file mode 100644 index 0000000..eb160f6 --- /dev/null +++ b/collectors/likwid/groups/westmereEX/CACHE.txt @@ -0,0 +1,25 @@ +SHORT Data cache miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 L1D_REPL + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +data cache misses PMC0 +data cache miss rate PMC0/FIXC0 + +LONG +Formulas: +data cache misses = L1D_REPL +data cache miss rate = L1D_REPL / INSTR_RETIRED_ANY +- +This group measures the locality of your data accesses with regard to the L1 +cache. The data cache miss rate gives a measure how often it was necessary to +get cache lines from higher levels of the memory hierarchy. + diff --git a/collectors/likwid/groups/westmereEX/DATA.txt b/collectors/likwid/groups/westmereEX/DATA.txt new file mode 100644 index 0000000..31bba51 --- /dev/null +++ b/collectors/likwid/groups/westmereEX/DATA.txt @@ -0,0 +1,22 @@ +SHORT Load to store ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 MEM_INST_RETIRED_LOADS +PMC1 MEM_INST_RETIRED_STORES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Load to store ratio PMC0/PMC1 + +LONG +Formulas: +Load to store ratio = MEM_INST_RETIRED_LOADS/MEM_INST_RETIRED_STORES +- +This is a simple metric to determine your load to store ratio. + diff --git a/collectors/likwid/groups/westmereEX/DIVIDE.txt b/collectors/likwid/groups/westmereEX/DIVIDE.txt new file mode 100644 index 0000000..2677a19 --- /dev/null +++ b/collectors/likwid/groups/westmereEX/DIVIDE.txt @@ -0,0 +1,24 @@ +SHORT Divide unit information + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 ARITH_NUM_DIV +PMC1 ARITH_CYCLES_DIV_BUSY + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Number of divide ops PMC0 +Avg. divide unit usage duration PMC1/PMC0 + +LONG +Formulas: +Number of divide ops = ARITH_NUM_DIV +Avg. divide unit usage duration = ARITH_CYCLES_DIV_BUSY/ARITH_NUM_DIV +- +This performance group measures the average latency of divide operations diff --git a/collectors/likwid/groups/westmereEX/FLOPS_DP.txt b/collectors/likwid/groups/westmereEX/FLOPS_DP.txt new file mode 100644 index 0000000..0c2e56c --- /dev/null +++ b/collectors/likwid/groups/westmereEX/FLOPS_DP.txt @@ -0,0 +1,35 @@ +SHORT Double Precision MFLOP/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 FP_COMP_OPS_EXE_SSE_FP_PACKED +PMC1 FP_COMP_OPS_EXE_SSE_FP_SCALAR +PMC2 FP_COMP_OPS_EXE_SSE_SINGLE_PRECISION +PMC3 FP_COMP_OPS_EXE_SSE_DOUBLE_PRECISION + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +DP [MFLOP/s] 1.0E-06*(PMC0*2.0+PMC1)/time +Packed [MUOPS/s] 1.0E-06*PMC0/time +Scalar [MUOPS/s] 1.0E-06*PMC1/time +SP [MUOPS/s] 1.0E-06*PMC2/time +DP [MUOPS/s] 1.0E-06*PMC3/time + +LONG +Formulas: +DP [MFLOP/s] = 1.0E-06*(FP_COMP_OPS_EXE_SSE_FP_PACKED*2+FP_COMP_OPS_EXE_SSE_FP_SCALAR)/runtime +Packed [MUOPS/s] = 1.0E-06*FP_COMP_OPS_EXE_SSE_FP_PACKED/runtime +Scalar [MUOPS/s] = 1.0E-06*FP_COMP_OPS_EXE_SSE_FP_SCALAR/runtime +SP [MUOPS/s] = 1.0E-06*FP_COMP_OPS_EXE_SSE_SINGLE_PRECISION/runtime +DP [MUOPS/s] = 1.0E-06*FP_COMP_OPS_EXE_SSE_DOUBLE_PRECISION/runtime +- +The Nehalem has no possibility to measure MFLOPs if mixed precision calculations are done. +Therefore both single as well as double precision are measured to ensure the correctness +of the measurements. You can check if your code was vectorized on the number of +FP_COMP_OPS_EXE_SSE_FP_PACKED versus the FP_COMP_OPS_EXE_SSE_FP_SCALAR. + diff --git a/collectors/likwid/groups/westmereEX/FLOPS_SP.txt b/collectors/likwid/groups/westmereEX/FLOPS_SP.txt new file mode 100644 index 0000000..d7c8e8e --- /dev/null +++ b/collectors/likwid/groups/westmereEX/FLOPS_SP.txt @@ -0,0 +1,35 @@ +SHORT Single Precision MFLOP/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 FP_COMP_OPS_EXE_SSE_FP_PACKED +PMC1 FP_COMP_OPS_EXE_SSE_FP_SCALAR +PMC2 FP_COMP_OPS_EXE_SSE_SINGLE_PRECISION +PMC3 FP_COMP_OPS_EXE_SSE_DOUBLE_PRECISION + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +SP [MFLOP/s] 1.0E-06*(PMC0*4.0+PMC1)/time +Packed [MUOPS/s] 1.0E-06*PMC0/time +Scalar [MUOPS/s] 1.0E-06*PMC1/time +SP [MUOPS/s] 1.0E-06*PMC2/time +DP [MUOPS/s] 1.0E-06*PMC3/time + +LONG +Formulas: +SP [MFLOP/s] = 1.0E-06*(FP_COMP_OPS_EXE_SSE_FP_PACKED*4+FP_COMP_OPS_EXE_SSE_FP_SCALAR)/runtime +Packed [MUOPS/s] = 1.0E-06*FP_COMP_OPS_EXE_SSE_FP_PACKED/runtime +Scalar [MUOPS/s] = 1.0E-06*FP_COMP_OPS_EXE_SSE_FP_SCALAR/runtime +SP [MUOPS/s] = 1.0E-06*FP_COMP_OPS_EXE_SSE_SINGLE_PRECISION/runtime +DP [MUOPS/s] = 1.0E-06*FP_COMP_OPS_EXE_SSE_DOUBLE_PRECISION/runtime +- +The Westmere EX has no possibility to measure MFLOPs if mixed precision calculations are done. +Therefore both single as well as double precision are measured to ensure the correctness +of the measurements. You can check if your code was vectorized on the number of +FP_COMP_OPS_EXE_SSE_FP_PACKED versus the FP_COMP_OPS_EXE_SSE_FP_SCALAR. + diff --git a/collectors/likwid/groups/westmereEX/FLOPS_X87.txt b/collectors/likwid/groups/westmereEX/FLOPS_X87.txt new file mode 100644 index 0000000..39cd8b4 --- /dev/null +++ b/collectors/likwid/groups/westmereEX/FLOPS_X87.txt @@ -0,0 +1,21 @@ +SHORT X87 MFLOP/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 INST_RETIRED_X87 + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +X87 [MFLOP/s] 1.0E-06*PMC0/time + +LONG +Formulas: +X87 [MFLOP/s] = 1.0E-06*INST_RETIRED_X87/runtime +- +Profiling group to measure X87 FLOP rate. + diff --git a/collectors/likwid/groups/westmereEX/ICACHE.txt b/collectors/likwid/groups/westmereEX/ICACHE.txt new file mode 100644 index 0000000..49943ff --- /dev/null +++ b/collectors/likwid/groups/westmereEX/ICACHE.txt @@ -0,0 +1,25 @@ +SHORT Instruction cache miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 L1I_READS +PMC1 L1I_MISSES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L1I request rate PMC0/FIXC0 +L1I miss rate PMC1/FIXC0 +L1I miss ratio PMC1/PMC0 + +LONG +Formulas: +L1I request rate = L1I_READS / INSTR_RETIRED_ANY +L1I miss rate = ICACHE_MISSES / INSTR_RETIRED_ANY +L1I miss ratio = ICACHE_MISSES / L1I_READS +- +This group measures some L1 instruction cache metrics. diff --git a/collectors/likwid/groups/westmereEX/L2.txt b/collectors/likwid/groups/westmereEX/L2.txt new file mode 100644 index 0000000..e950021 --- /dev/null +++ b/collectors/likwid/groups/westmereEX/L2.txt @@ -0,0 +1,38 @@ +SHORT L2 cache bandwidth in MBytes/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 L1D_REPL +PMC1 L1D_M_EVICT +PMC2 L1I_MISSES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L2D load bandwidth [MBytes/s] 1.0E-06*PMC0*64.0/time +L2D load data volume [GBytes] 1.0E-09*PMC0*64.0 +L2D evict bandwidth [MBytes/s] 1.0E-06*PMC1*64.0/time +L2D evict data volume [GBytes] 1.0E-09*PMC1*64.0 +L2 bandwidth [MBytes/s] 1.0E-06*(PMC0+PMC1+PMC2)*64.0/time +L2 data volume [GBytes] 1.0E-09*(PMC0+PMC1+PMC2)*64.0 + +LONG +Formulas: +L2D load bandwidth [MBytes/s] = 1.0E-06*L1D_REPL*64.0/time +L2D load data volume [GBytes] = 1.0E-09*L1D_REPL*64.0 +L2D evict bandwidth [MBytes/s] = 1.0E-06*L1D_M_EVICT*64.0/time +L2D evict data volume [GBytes] = 1.0E-09*L1D_M_EVICT*64.0 +L2 bandwidth [MBytes/s] = 1.0E-06*(L1D_REPL+L1D_M_EVICT+L1I_MISSES)*64/time +L2 data volume [GBytes] = 1.0E-09*(L1D_REPL+L1D_M_EVICT+L1I_MISSES)*64 +- +Profiling group to measure L2 cache bandwidth. The bandwidth is computed by the +number of cache line allocated in the L1 and the number of modified cache lines +evicted from the L1. Also reports on total data volume transferred between L2 +and L1 cache. Note that this bandwidth also includes data transfers due to a +write allocate load on a store miss in L1 and traffic caused by misses in the +instruction cache. + diff --git a/collectors/likwid/groups/westmereEX/L2CACHE.txt b/collectors/likwid/groups/westmereEX/L2CACHE.txt new file mode 100644 index 0000000..343b263 --- /dev/null +++ b/collectors/likwid/groups/westmereEX/L2CACHE.txt @@ -0,0 +1,34 @@ +SHORT L2 cache miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 L2_RQSTS_REFERENCES +PMC1 L2_RQSTS_MISS + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L2 request rate PMC0/FIXC0 +L2 miss rate PMC1/FIXC0 +L2 miss ratio PMC1/PMC0 + +LONG +Formulas: +L2 request rate = L2_RQSTS_REFERENCES/INSTR_RETIRED_ANY +L2 miss rate = L2_RQSTS_MISS/INSTR_RETIRED_ANY +L2 miss ratio = L2_RQSTS_MISS/L2_RQSTS_REFERENCES +- +This group measures the locality of your data accesses with regard to the +L2 cache. L2 request rate tells you how data intensive your code is +or how many data accesses you have on average per instruction. +The L2 miss rate gives a measure how often it was necessary to get +cache lines from memory. And finally L2 miss ratio tells you how many of your +memory references required a cache line to be loaded from a higher level. +While the data cache miss rate might be given by your algorithm you should +try to get data cache miss ratio as low as possible by increasing your cache reuse. + + diff --git a/collectors/likwid/groups/westmereEX/L3.txt b/collectors/likwid/groups/westmereEX/L3.txt new file mode 100644 index 0000000..7e5cb04 --- /dev/null +++ b/collectors/likwid/groups/westmereEX/L3.txt @@ -0,0 +1,36 @@ +SHORT L3 cache bandwidth in MBytes/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 L2_LINES_IN_ANY +PMC1 L2_LINES_OUT_DEMAND_DIRTY + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L3 load bandwidth [MBytes/s] 1.0E-06*PMC0*64.0/time +L3 load data volume [GBytes] 1.0E-09*PMC0*64.0 +L3 evict bandwidth [MBytes/s] 1.0E-06*PMC1*64.0/time +L3 evict data volume [GBytes] 1.0E-09*PMC1*64.0 +L3 bandwidth [MBytes/s] 1.0E-06*(PMC0+PMC1)*64.0/time +L3 data volume [GBytes] 1.0E-09*(PMC0+PMC1)*64.0 + +LONG +Formulas: +L3 load bandwidth [MBytes/s] = 1.0E-06*L2_LINES_IN_ANY*64.0/time +L3 load data volume [GBytes] = 1.0E-09*L2_LINES_IN_ANY*64.0 +L3 evict bandwidth [MBytes/s] = 1.0E-06*L2_LINES_OUT_DEMAND_DIRTY*64.0/time +L3 evict data volume [GBytes] = 1.0E-09*L2_LINES_OUT_DEMAND_DIRTY*64.0 +L3 bandwidth [MBytes/s] = 1.0E-06*(L2_LINES_IN_ANY+L2_LINES_OUT_DEMAND_DIRTY)*64/time +L3 data volume [GBytes] = 1.0E-09*(L2_LINES_IN_ANY+L2_LINES_OUT_DEMAND_DIRTY)*64 +- +Profiling group to measure L3 cache bandwidth. The bandwidth is +computed by the number of cache line allocated in the L2 and the number of +modified cache lines evicted from the L2. Also reporto data volume transferred +between L3 and L2 caches. Note that this bandwidth also includes data transfers +due to a write allocate load on a store miss in L2. + diff --git a/collectors/likwid/groups/westmereEX/L3CACHE.txt b/collectors/likwid/groups/westmereEX/L3CACHE.txt new file mode 100644 index 0000000..262f948 --- /dev/null +++ b/collectors/likwid/groups/westmereEX/L3CACHE.txt @@ -0,0 +1,52 @@ +SHORT L3 cache miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +CBOX0C0 LLC_HITS_ALL +CBOX0C1 LLC_MISSES_ALL +CBOX1C0 LLC_HITS_ALL +CBOX1C1 LLC_MISSES_ALL +CBOX2C0 LLC_HITS_ALL +CBOX2C1 LLC_MISSES_ALL +CBOX3C0 LLC_HITS_ALL +CBOX3C1 LLC_MISSES_ALL +CBOX4C0 LLC_HITS_ALL +CBOX4C1 LLC_MISSES_ALL +CBOX5C0 LLC_HITS_ALL +CBOX5C1 LLC_MISSES_ALL +CBOX6C0 LLC_HITS_ALL +CBOX6C1 LLC_MISSES_ALL +CBOX7C0 LLC_HITS_ALL +CBOX7C1 LLC_MISSES_ALL +CBOX8C0 LLC_HITS_ALL +CBOX8C1 LLC_MISSES_ALL +CBOX9C0 LLC_HITS_ALL +CBOX9C1 LLC_MISSES_ALL + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L3 request rate (CBOX0C0+CBOX0C1+CBOX1C0+CBOX1C1+CBOX2C0+CBOX2C1+CBOX3C0+CBOX3C1+CBOX4C0+CBOX4C1+CBOX5C0+CBOX5C1+CBOX6C0+CBOX6C1+CBOX7C0+CBOX7C1+CBOX8C0+CBOX8C1+CBOX9C0+CBOX9C1)/FIXC0 +L3 miss rate (CBOX0C1+CBOX1C1+CBOX2C1+CBOX3C1+CBOX4C1+CBOX5C1+CBOX6C1+CBOX7C1+CBOX8C1+CBOX9C1)/FIXC0 +L3 miss ratio (CBOX0C1+CBOX1C1+CBOX2C1+CBOX3C1+CBOX4C1+CBOX5C1+CBOX6C1+CBOX7C1+CBOX8C1+CBOX9C1)/(CBOX0C0+CBOX0C1+CBOX1C0+CBOX1C1+CBOX2C0+CBOX2C1+CBOX3C0+CBOX3C1+CBOX4C0+CBOX4C1+CBOX5C0+CBOX5C1+CBOX6C0+CBOX6C1+CBOX7C0+CBOX7C1+CBOX8C0+CBOX8C1+CBOX9C0+CBOX9C1) + +LONG +Formulas: +L3 request rate = (SUM(LLC_HITS_ALL)+SUM(LLC_MISSES_ALL))/INSTR_RETIRED_ANY +L3 miss rate = SUM(LLC_MISSES_ALL)/INSTR_RETIRED_ANY +L3 miss ratio = SUM(LLC_MISSES_ALL)/(SUM(LLC_HITS_ALL)+SUM(LLC_MISSES_ALL)) +- +This group measures the locality of your data accesses with regard to the +L3 cache. L3 request rate tells you how data intensive your code is +or how many data accesses you have on average per instruction. +The L3 miss rate gives a measure how often it was necessary to get +cache lines from memory. And finally L3 miss ratio tells you how many of your +memory references required a cache line to be loaded from a higher level. +While the data cache miss rate might be given by your algorithm you should +try to get data cache miss ratio as low as possible by increasing your cache reuse. + + diff --git a/collectors/likwid/groups/westmereEX/MEM.txt b/collectors/likwid/groups/westmereEX/MEM.txt new file mode 100644 index 0000000..5d4fc62 --- /dev/null +++ b/collectors/likwid/groups/westmereEX/MEM.txt @@ -0,0 +1,38 @@ +SHORT Main memory bandwidth in MBytes/s + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +MBOX0C0 FVC_EV0_BBOX_CMDS_READS +MBOX0C1 DRAM_CMD_CAS_WR_OPN +MBOX0C2 DRAM_MISC_CAS_WR_CLS +MBOX1C0 FVC_EV0_BBOX_CMDS_READS +MBOX1C1 DRAM_CMD_CAS_WR_OPN +MBOX1C2 DRAM_MISC_CAS_WR_CLS + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Memory read bandwidth [MBytes/s] 1.0E-06*(MBOX0C0+MBOX1C0)*64.0/time +Memory read data volume [GBytes] 1.0E-09*(MBOX0C0+MBOX1C0)*64.0 +Memory write bandwidth [MBytes/s] 1.0E-06*(MBOX0C1+MBOX0C2+MBOX1C1+MBOX1C2)*64.0/time +Memory write data volume [GBytes] 1.0E-09*(MBOX0C1+MBOX0C2+MBOX1C1+MBOX1C2)*64.0 +Memory bandwidth [MBytes/s] 1.0E-06*(MBOX0C0+MBOX1C0+MBOX0C1+MBOX1C1+MBOX0C2+MBOX1C2)*64/time +Memory data volume [GBytes] 1.0E-09*(MBOX0C0+MBOX1C0+MBOX0C1+MBOX1C1+MBOX0C2+MBOX1C2)*64 + +LONG +Formulas: +Memory read bandwidth [MBytes/s] = 1.0E-06*(SUM(MBOXxC0))*64.0/time +Memory read data volume [GBytes] = 1.0E-09*(SUM(MBOXxC0))*64.0 +Memory write bandwidth [MBytes/s] = 1.0E-06*(SUM(MBOXxC1)+SUM(MBOXxC2))*64.0/time +Memory write data volume [GBytes] = 1.0E-09*(SUM(MBOXxC1)+SUM(MBOXxC2))*64.0 +Memory bandwidth [MBytes/s] = 1.0E-06*(SUM(MBOXxC0)+SUM(MBOXxC1)+SUM(MBOXxC2))*64.0/time +Memory data volume [GBytes] = 1.0E-09*(SUM(MBOXxC0)+SUM(MBOXxC1)+SUM(MBOXxC2))*64.0 +- +Profiling group to measure memory bandwidth drawn by all cores of a socket. +Addional to the bandwidth it also outputs the data volume. + diff --git a/collectors/likwid/groups/westmereEX/NUMA.txt b/collectors/likwid/groups/westmereEX/NUMA.txt new file mode 100644 index 0000000..41fbe62 --- /dev/null +++ b/collectors/likwid/groups/westmereEX/NUMA.txt @@ -0,0 +1,33 @@ +SHORT Local and remote memory accesses + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 OFFCORE_RESPONSE_0_LOCAL_DRAM +PMC1 OFFCORE_RESPONSE_1_REMOTE_DRAM + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Local DRAM data volume [GByte] 1.E-09*PMC0*64 +Local DRAM bandwidth [MByte/s] 1.E-06*(PMC0*64)/time +Remote DRAM data volume [GByte] 1.E-09*PMC1*64 +Remote DRAM bandwidth [MByte/s] 1.E-06*(PMC1*64)/time +Memory data volume [GByte] 1.E-09*(PMC0+PMC1)*64 +Memory bandwidth [MByte/s] 1.E-06*((PMC0+PMC1)*64)/time + +LONG +Formulas: +CPI = CPU_CLK_UNHALTED_CORE/INSTR_RETIRED_ANY +Local DRAM data volume [GByte] = 1.E-09*OFFCORE_RESPONSE_0_LOCAL_DRAM*64 +Local DRAM bandwidth [MByte/s] = 1.E-06*(OFFCORE_RESPONSE_0_LOCAL_DRAM*64)/time +Remote DRAM data volume [GByte] = 1.E-09*OFFCORE_RESPONSE_1_REMOTE_DRAM*64 +Remote DRAM bandwidth [MByte/s] = 1.E-06*(OFFCORE_RESPONSE_1_REMOTE_DRAM*64)/time +Memory data volume [GByte] = 1.E-09*(OFFCORE_RESPONSE_0_LOCAL_DRAM+OFFCORE_RESPONSE_1_REMOTE_DRAM)*64 +Memory bandwidth [MByte/s] = 1.E-06*((OFFCORE_RESPONSE_0_LOCAL_DRAM+OFFCORE_RESPONSE_1_REMOTE_DRAM)*64)/time +-- +This performance group measures the data traffic of CPU cores to local and remote +memory. diff --git a/collectors/likwid/groups/westmereEX/TLB_DATA.txt b/collectors/likwid/groups/westmereEX/TLB_DATA.txt new file mode 100644 index 0000000..d256b8c --- /dev/null +++ b/collectors/likwid/groups/westmereEX/TLB_DATA.txt @@ -0,0 +1,35 @@ +SHORT L2 data TLB miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 DTLB_LOAD_MISSES_ANY +PMC1 DTLB_MISSES_ANY +PMC2 DTLB_LOAD_MISSES_WALK_CYCLES +PMC3 DTLB_MISSES_WALK_CYCLES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L1 DTLB load misses PMC0 +L1 DTLB load miss rate PMC0/FIXC0 +L1 DTLB load miss duration [Cyc] PMC2/PMC0 +L1 DTLB store misses (PMC1-PMC0) +L1 DTLB store miss rate (PMC1-PMC0)/FIXC0 +L1 DTLB store miss duration [Cyc] (PMC3-PMC2)/(PMC1-PMC0) + +LONG +Formulas: +L1 DTLB load misses = DTLB_LOAD_MISSES_ANY +L1 DTLB load miss rate = DTLB_LOAD_MISSES_ANY / INSTR_RETIRED_ANY +L1 DTLB load miss duration [Cyc] = DTLB_LOAD_MISSES_WALK_CYCLES / DTLB_LOAD_MISSES_ANY +L1 DTLB store misses = DTLB_MISSES_ANY-DTLB_LOAD_MISSES_ANY +L1 DTLB store miss rate = (DTLB_MISSES_ANY-DTLB_LOAD_MISSES_ANY) / INSTR_RETIRED_ANY +L1 DTLB store miss duration [Cyc] = (DTLB_MISSES_WALK_CYCLES-DTLB_LOAD_MISSES_WALK_CYCLES) / (DTLB_MISSES_ANY-DTLB_LOAD_MISSES_ANY) +- +The DTLB miss rate gives a measure how often a TLB miss occurred +per instruction. The store miss calculations are done using ALL-LOADS TLB walks. + diff --git a/collectors/likwid/groups/westmereEX/TLB_INSTR.txt b/collectors/likwid/groups/westmereEX/TLB_INSTR.txt new file mode 100644 index 0000000..2f0f90c --- /dev/null +++ b/collectors/likwid/groups/westmereEX/TLB_INSTR.txt @@ -0,0 +1,27 @@ +SHORT L1 Instruction TLB miss rate/ratio + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 ITLB_MISSES_ANY +PMC1 ITLB_MISSES_WALK_CYCLES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +L1 ITLB misses PMC0 +L1 ITLB miss rate PMC0/FIXC0 +L1 ITLB miss duration [Cyc] PMC1/PMC0 + +LONG +Formulas: +L1 ITLB misses = ITLB_MISSES_ANY +L1 ITLB miss rate = ITLB_MISSES_ANY / INSTR_RETIRED_ANY +L1 ITLB miss duration [Cyc] = ITLB_MISSES_WALK_CYCLES / ITLB_MISSES_ANY +- +The ITLB miss rates gives a measure how often a TLB miss occurred +per instruction. The duration measures the time in cycles how long a walk did take. + diff --git a/collectors/likwid/groups/westmereEX/UOPS.txt b/collectors/likwid/groups/westmereEX/UOPS.txt new file mode 100644 index 0000000..f58fda6 --- /dev/null +++ b/collectors/likwid/groups/westmereEX/UOPS.txt @@ -0,0 +1,32 @@ +SHORT UOPs execution info + +EVENTSET +FIXC0 INSTR_RETIRED_ANY +FIXC1 CPU_CLK_UNHALTED_CORE +FIXC2 CPU_CLK_UNHALTED_REF +PMC0 UOPS_ISSUED_ANY +PMC2 UOPS_RETIRED_ANY +PMC3 UOPS_ISSUED_FUSED + + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/FIXC0 +Issued UOPs PMC0 +Merged UOPs PMC3 +Retired UOPs PMC2 + +LONG +Formulas: +Issued UOPs = UOPS_ISSUED_ANY +Merged UOPs = UOPS_ISSUED_FUSED +Retired UOPs = UOPS_RETIRED_ANY +- +This group returns information about the instruction pipeline. It measures the +issued, executed and retired uOPs and returns the number of uOPs which were issued +but not executed as well as the number of uOPs which were executed but never retired. +The executed but not retired uOPs commonly come from speculatively executed branches. + diff --git a/collectors/likwid/groups/zen/BRANCH.txt b/collectors/likwid/groups/zen/BRANCH.txt new file mode 100644 index 0000000..dbaf07f --- /dev/null +++ b/collectors/likwid/groups/zen/BRANCH.txt @@ -0,0 +1,32 @@ +SHORT Branch prediction miss rate/ratio + +EVENTSET +FIXC1 ACTUAL_CPU_CLOCK +FIXC2 MAX_CPU_CLOCK +PMC0 RETIRED_INSTRUCTIONS +PMC1 CPU_CLOCKS_UNHALTED +PMC2 RETIRED_BRANCH_INSTR +PMC3 RETIRED_MISP_BRANCH_INSTR + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI PMC1/PMC0 +Branch rate PMC2/PMC0 +Branch misprediction rate PMC3/PMC0 +Branch misprediction ratio PMC3/PMC2 +Instructions per branch PMC0/PMC2 + +LONG +Formulas: +Branch rate = RETIRED_BRANCH_INSTR/RETIRED_INSTRUCTIONS +Branch misprediction rate = RETIRED_MISP_BRANCH_INSTR/RETIRED_INSTRUCTIONS +Branch misprediction ratio = RETIRED_MISP_BRANCH_INSTR/RETIRED_BRANCH_INSTR +Instructions per branch = RETIRED_INSTRUCTIONS/RETIRED_BRANCH_INSTR +- +The rates state how often on average a branch or a mispredicted branch occurred +per instruction retired in total. The branch misprediction ratio sets directly +into relation what ratio of all branch instruction where mispredicted. +Instructions per branch is 1/branch rate. + diff --git a/collectors/likwid/groups/zen/CACHE.txt b/collectors/likwid/groups/zen/CACHE.txt new file mode 100644 index 0000000..b773e5a --- /dev/null +++ b/collectors/likwid/groups/zen/CACHE.txt @@ -0,0 +1,39 @@ +SHORT Data cache miss rate/ratio + +EVENTSET +FIXC1 ACTUAL_CPU_CLOCK +FIXC2 MAX_CPU_CLOCK +PMC0 RETIRED_INSTRUCTIONS +PMC1 CPU_CLOCKS_UNHALTED +PMC2 DATA_CACHE_ACCESSES +PMC3 DATA_CACHE_REFILLS_ALL + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI PMC1/PMC0 +data cache requests PMC2 +data cache request rate PMC2/PMC0 +data cache misses PMC3 +data cache miss rate PMC3/PMC0 +data cache miss ratio PMC3/PMC2 + +LONG +Formulas: +data cache requests = DATA_CACHE_ACCESSES +data cache request rate = DATA_CACHE_ACCESSES / RETIRED_INSTRUCTIONS +data cache misses = DATA_CACHE_REFILLS_ALL +data cache miss rate = DATA_CACHE_REFILLS_ALL / RETIRED_INSTRUCTIONS +data cache miss ratio = DATA_CACHE_REFILLS_ALL / DATA_CACHE_ACCESSES +- +This group measures the locality of your data accesses with regard to the +L1 cache. Data cache request rate tells you how data intensive your code is +or how many data accesses you have on average per instruction. +The data cache miss rate gives a measure how often it was necessary to get +cache lines from higher levels of the memory hierarchy. And finally +data cache miss ratio tells you how many of your memory references required +a cache line to be loaded from a higher level. While the# data cache miss rate +might be given by your algorithm you should try to get data cache miss ratio +as low as possible by increasing your cache reuse. + diff --git a/collectors/likwid/groups/zen/CPI.txt b/collectors/likwid/groups/zen/CPI.txt new file mode 100644 index 0000000..23e4f8c --- /dev/null +++ b/collectors/likwid/groups/zen/CPI.txt @@ -0,0 +1,30 @@ +SHORT Cycles per instruction + +EVENTSET +FIXC1 ACTUAL_CPU_CLOCK +FIXC2 MAX_CPU_CLOCK +PMC0 RETIRED_INSTRUCTIONS +PMC1 CPU_CLOCKS_UNHALTED +PMC2 RETIRED_UOPS + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] PMC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI PMC1/PMC0 +CPI (based on uops) PMC1/PMC2 +IPC PMC0/PMC1 + + +LONG +Formulas: +CPI = CPU_CLOCKS_UNHALTED/RETIRED_INSTRUCTIONS +CPI (based on uops) = CPU_CLOCKS_UNHALTED/RETIRED_UOPS +IPC = RETIRED_INSTRUCTIONS/CPU_CLOCKS_UNHALTED +- +This group measures how efficient the processor works with +regard to instruction throughput. Also important as a standalone +metric is RETIRED_INSTRUCTIONS as it tells you how many instruction +you need to execute for a task. An optimization might show very +low CPI values but execute many more instruction for it. + diff --git a/collectors/likwid/groups/zen/DATA.txt b/collectors/likwid/groups/zen/DATA.txt new file mode 100644 index 0000000..e061b90 --- /dev/null +++ b/collectors/likwid/groups/zen/DATA.txt @@ -0,0 +1,23 @@ +SHORT Load to store ratio + +EVENTSET +FIXC1 ACTUAL_CPU_CLOCK +FIXC2 MAX_CPU_CLOCK +PMC0 RETIRED_INSTRUCTIONS +PMC1 CPU_CLOCKS_UNHALTED +PMC2 LS_DISPATCH_LOADS +PMC3 LS_DISPATCH_STORES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI PMC1/PMC0 +Load to store ratio PMC2/PMC3 + +LONG +Formulas: +Load to store ratio = LS_DISPATCH_LOADS/LS_DISPATCH_STORES +- +This is a simple metric to determine your load to store ratio. + diff --git a/collectors/likwid/groups/zen/DIVIDE.txt b/collectors/likwid/groups/zen/DIVIDE.txt new file mode 100644 index 0000000..c98500b --- /dev/null +++ b/collectors/likwid/groups/zen/DIVIDE.txt @@ -0,0 +1,26 @@ +SHORT Divide unit information + +EVENTSET +FIXC1 ACTUAL_CPU_CLOCK +FIXC2 MAX_CPU_CLOCK +PMC0 RETIRED_INSTRUCTIONS +PMC1 CPU_CLOCKS_UNHALTED +PMC2 DIV_OP_COUNT +PMC3 DIV_BUSY_CYCLES + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI PMC1/PMC0 +Number of divide ops PMC2 +Avg. divide unit usage duration PMC3/PMC2 + +LONG +Formulas: +CPI = CPU_CLOCKS_UNHALTED/RETIRED_INSTRUCTIONS +Number of divide ops = DIV_OP_COUNT +Avg. divide unit usage duration = DIV_BUSY_CYCLES/DIV_OP_COUNT +- +This performance group measures the average latency of divide operations diff --git a/collectors/likwid/groups/zen/ENERGY.txt b/collectors/likwid/groups/zen/ENERGY.txt new file mode 100644 index 0000000..f58c5b1 --- /dev/null +++ b/collectors/likwid/groups/zen/ENERGY.txt @@ -0,0 +1,32 @@ +SHORT Power and Energy consumption + +EVENTSET +FIXC1 ACTUAL_CPU_CLOCK +FIXC2 MAX_CPU_CLOCK +PMC0 RETIRED_INSTRUCTIONS +PMC1 CPU_CLOCKS_UNHALTED +PWR0 RAPL_CORE_ENERGY +PWR1 RAPL_PKG_ENERGY + + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI PMC1/PMC0 +Energy Core [J] PWR0 +Power Core [W] PWR0/time +Energy PKG [J] PWR1 +Power PKG [W] PWR1/time + +LONG +Formulas: +Power Core [W] = RAPL_CORE_ENERGY/time +Power PKG [W] = RAPL_PKG_ENERGY/time +- +Ryzen implements the RAPL interface previously introduced by Intel. +This interface enables to monitor the consumed energy on the core and package +domain. +It is not documented by AMD which parts of the CPU are in which domain. + diff --git a/collectors/likwid/groups/zen/FLOPS_DP.txt b/collectors/likwid/groups/zen/FLOPS_DP.txt new file mode 100644 index 0000000..420f942 --- /dev/null +++ b/collectors/likwid/groups/zen/FLOPS_DP.txt @@ -0,0 +1,26 @@ +SHORT Double Precision MFLOP/s + +EVENTSET +FIXC1 ACTUAL_CPU_CLOCK +FIXC2 MAX_CPU_CLOCK +PMC0 RETIRED_INSTRUCTIONS +PMC1 CPU_CLOCKS_UNHALTED +PMC2 RETIRED_SSE_AVX_FLOPS_DOUBLE_ALL +PMC3 MERGE + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI PMC1/PMC0 +DP [MFLOP/s] 1.0E-06*(PMC2)/time + +LONG +Formulas: +CPI = CPU_CLOCKS_UNHALTED/RETIRED_INSTRUCTIONS +DP [MFLOP/s] = 1.0E-06*(RETIRED_SSE_AVX_FLOPS_DOUBLE_ALL)/time +- +Profiling group to measure double precisision FLOP rate. The event might +have a higher per-cycle increment than 15, so the MERGE event is required. + + diff --git a/collectors/likwid/groups/zen/FLOPS_SP.txt b/collectors/likwid/groups/zen/FLOPS_SP.txt new file mode 100644 index 0000000..1f64af1 --- /dev/null +++ b/collectors/likwid/groups/zen/FLOPS_SP.txt @@ -0,0 +1,26 @@ +SHORT Single Precision MFLOP/s + +EVENTSET +FIXC1 ACTUAL_CPU_CLOCK +FIXC2 MAX_CPU_CLOCK +PMC0 RETIRED_INSTRUCTIONS +PMC1 CPU_CLOCKS_UNHALTED +PMC2 RETIRED_SSE_AVX_FLOPS_SINGLE_ALL +PMC3 MERGE + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI PMC1/PMC0 +SP [MFLOP/s] 1.0E-06*(PMC2)/time + +LONG +Formulas: +CPI = CPU_CLOCKS_UNHALTED/RETIRED_INSTRUCTIONS +SP [MFLOP/s] = 1.0E-06*(RETIRED_SSE_AVX_FLOPS_SINGLE_ALL)/time +- +Profiling group to measure single precisision FLOP rate. The event might +have a higher per-cycle increment than 15, so the MERGE event is required. + + diff --git a/collectors/likwid/groups/zen/ICACHE.txt b/collectors/likwid/groups/zen/ICACHE.txt new file mode 100644 index 0000000..f98c28a --- /dev/null +++ b/collectors/likwid/groups/zen/ICACHE.txt @@ -0,0 +1,28 @@ +SHORT Instruction cache miss rate/ratio + +EVENTSET +FIXC1 ACTUAL_CPU_CLOCK +FIXC2 MAX_CPU_CLOCK +PMC0 RETIRED_INSTRUCTIONS +PMC1 ICACHE_FETCHES +PMC2 ICACHE_L2_REFILLS +PMC3 ICACHE_SYSTEM_REFILLS + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/PMC0 +L1I request rate PMC1/PMC0 +L1I miss rate (PMC2+PMC3)/PMC0 +L1I miss ratio (PMC2+PMC3)/PMC1 + +LONG +Formulas: +L1I request rate = ICACHE_FETCHES / RETIRED_INSTRUCTIONS +L1I miss rate = (ICACHE_L2_REFILLS + ICACHE_SYSTEM_REFILLS)/RETIRED_INSTRUCTIONS +L1I miss ratio = (ICACHE_L2_REFILLS + ICACHE_SYSTEM_REFILLS)/ICACHE_FETCHES +- +This group measures the locality of your instruction code with regard to the +L1 I-Cache. + diff --git a/collectors/likwid/groups/zen/L2.txt b/collectors/likwid/groups/zen/L2.txt new file mode 100644 index 0000000..420e34d --- /dev/null +++ b/collectors/likwid/groups/zen/L2.txt @@ -0,0 +1,28 @@ +SHORT L2 cache bandwidth in MBytes/s (experimental) + +EVENTSET +FIXC1 ACTUAL_CPU_CLOCK +FIXC2 MAX_CPU_CLOCK +PMC0 RETIRED_INSTRUCTIONS +PMC1 CPU_CLOCKS_UNHALTED +PMC3 REQUESTS_TO_L2_GRP1_ALL_NO_PF + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI PMC1/PMC0 +L2D load bandwidth [MBytes/s] 1.0E-06*PMC3*64.0/time +L2D load data volume [GBytes] 1.0E-09*PMC3*64.0 +L2 bandwidth [MBytes/s] 1.0E-06*(PMC3)*64.0/time +L2 data volume [GBytes] 1.0E-09*(PMC3)*64.0 + +LONG +Formulas: +L2D load bandwidth [MBytes/s] = 1.0E-06*REQUESTS_TO_L2_GRP1_ALL_NO_PF*64.0/time +L2D load data volume [GBytes] = 1.0E-09*REQUESTS_TO_L2_GRP1_ALL_NO_PF*64.0 +L2 bandwidth [MBytes/s] = 1.0E-06*(REQUESTS_TO_L2_GRP1_ALL_NO_PF)*64/time +L2 data volume [GBytes] = 1.0E-09*(REQUESTS_TO_L2_GRP1_ALL_NO_PF)*64 +- +Profiling group to measure L2 cache bandwidth. There is no way to measure +the store traffic between L1 and L2. diff --git a/collectors/likwid/groups/zen/L3.txt b/collectors/likwid/groups/zen/L3.txt new file mode 100644 index 0000000..6fe808a --- /dev/null +++ b/collectors/likwid/groups/zen/L3.txt @@ -0,0 +1,32 @@ +SHORT L3 cache bandwidth in MBytes/s + +EVENTSET +FIXC1 ACTUAL_CPU_CLOCK +FIXC2 MAX_CPU_CLOCK +PMC0 RETIRED_INSTRUCTIONS +PMC1 CPU_CLOCKS_UNHALTED +CPMC0 L3_ACCESS +CPMC1 L3_MISS + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI PMC1/PMC0 +L3 access bandwidth [MBytes/s] 1.0E-06*CPMC0*64.0/time +L3 access data volume [GBytes] 1.0E-09*CPMC0*64.0 +L3 access rate [%] (CPMC0/PMC0)*100.0 +L3 miss rate [%] (CPMC1/PMC0)*100.0 +L3 miss ratio [%] (CPMC1/CPMC0)*100.0 + +LONG +Formulas: +L3 access bandwidth [MBytes/s] = 1.0E-06*L3_ACCESS*64.0/time +L3 access data volume [GBytes] = 1.0E-09*L3_ACCESS*64.0 +L3 access rate [%] = (L3_ACCESS/RETIRED_INSTRUCTIONS)*100 +L3 miss rate [%] = (L3_MISS/RETIRED_INSTRUCTIONS)*100 +L3 miss ratio [%]= (L3_MISS/L3_ACCESS)*100 +- +Profiling group to measure L3 cache bandwidth. There is no way to measure +the store traffic between L2 and L3. The only two published L3 events are +L3_ACCESS and L3_MISS. diff --git a/collectors/likwid/groups/zen/MEM.txt b/collectors/likwid/groups/zen/MEM.txt new file mode 100644 index 0000000..36ff58f --- /dev/null +++ b/collectors/likwid/groups/zen/MEM.txt @@ -0,0 +1,32 @@ +SHORT Main memory bandwidth in MBytes/s (experimental) + +EVENTSET +FIXC1 ACTUAL_CPU_CLOCK +FIXC2 MAX_CPU_CLOCK +PMC0 RETIRED_INSTRUCTIONS +PMC1 CPU_CLOCKS_UNHALTED +DFC0 DATA_FROM_LOCAL_DRAM_CHANNEL +DFC1 DATA_TO_LOCAL_DRAM_CHANNEL + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI PMC1/PMC0 +Memory bandwidth [MBytes/s] 1.0E-06*(DFC0+DFC1)*64.0/time +Memory data volume [GBytes] 1.0E-09*(DFC0+DFC1)*64.0 + +LONG +Formulas: +Memory bandwidth [MBytes/s] = 1.0E-06*(DATA_FROM_LOCAL_DRAM_CHANNEL+DATA_TO_LOCAL_DRAM_CHANNEL)*64.0/runtime +Memory data volume [GBytes] = 1.0E-09*(DATA_FROM_LOCAL_DRAM_CHANNEL+DATA_TO_LOCAL_DRAM_CHANNEL)*64.0 +- +Profiling group to measure memory bandwidth drawn by all cores of a socket. +Since this group is based on Uncore events it is only possible to measure on a +per socket base. +The group provides almost accurate results for the total bandwidth and data volume. +AMD describes this metric as "approximate" in the documentation for AMD Rome. + +Be aware that despite the events imply a traffic direction (FROM and TO), the events +cannot be used to differentiate between read and write traffic. The events will be +renamed to avoid that confusion in the future. diff --git a/collectors/likwid/groups/zen/MEM_DP.txt b/collectors/likwid/groups/zen/MEM_DP.txt new file mode 100644 index 0000000..9c2fe38 --- /dev/null +++ b/collectors/likwid/groups/zen/MEM_DP.txt @@ -0,0 +1,39 @@ +SHORT Overview of arithmetic and main memory performance + +EVENTSET +FIXC1 ACTUAL_CPU_CLOCK +FIXC2 MAX_CPU_CLOCK +PMC0 RETIRED_INSTRUCTIONS +PMC1 CPU_CLOCKS_UNHALTED +PMC2 RETIRED_SSE_AVX_FLOPS_DOUBLE_ALL +PMC3 MERGE +DFC0 DATA_FROM_LOCAL_DRAM_CHANNEL +DFC1 DATA_TO_LOCAL_DRAM_CHANNEL + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI PMC1/PMC0 +DP [MFLOP/s] 1.0E-06*(PMC2)/time +Memory bandwidth [MBytes/s] 1.0E-06*(DFC0+DFC1)*64.0/time +Memory data volume [GBytes] 1.0E-09*(DFC0+DFC1)*64.0 +Operational intensity PMC2/((DFC0+DFC1)*64.0) + +LONG +Formulas: +DP [MFLOP/s] = 1.0E-06*(RETIRED_SSE_AVX_FLOPS_DOUBLE_ALL)/time +Memory bandwidth [MBytes/s] = 1.0E-06*(DATA_FROM_LOCAL_DRAM_CHANNEL+DATA_TO_LOCAL_DRAM_CHANNEL)*64.0/runtime +Memory data volume [GBytes] = 1.0E-09*(DATA_FROM_LOCAL_DRAM_CHANNEL+DATA_TO_LOCAL_DRAM_CHANNEL)*64.0 +Operational intensity = RETIRED_SSE_AVX_FLOPS_DOUBLE_ALL/((DATA_FROM_LOCAL_DRAM_CHANNEL+DATA_TO_LOCAL_DRAM_CHANNEL)*64.0) +- +Profiling group to measure memory bandwidth drawn by all cores of a socket. +Since this group is based on Uncore events it is only possible to measure on a +per socket base. +The group provides almost accurate results for the total bandwidth and data volume. +AMD describes this metric as "approximate" in the documentation for AMD Rome. + +Be aware that despite the events imply a traffic direction (FROM and TO), the events +cannot be used to differentiate between read and write traffic. The events will be +renamed to avoid that confusion in the future. + diff --git a/collectors/likwid/groups/zen/MEM_SP.txt b/collectors/likwid/groups/zen/MEM_SP.txt new file mode 100644 index 0000000..48ce75c --- /dev/null +++ b/collectors/likwid/groups/zen/MEM_SP.txt @@ -0,0 +1,39 @@ +SHORT Overview of arithmetic and main memory performance + +EVENTSET +FIXC1 ACTUAL_CPU_CLOCK +FIXC2 MAX_CPU_CLOCK +PMC0 RETIRED_INSTRUCTIONS +PMC1 CPU_CLOCKS_UNHALTED +PMC2 RETIRED_SSE_AVX_FLOPS_SINGLE_ALL +PMC3 MERGE +DFC0 DATA_FROM_LOCAL_DRAM_CHANNEL +DFC1 DATA_TO_LOCAL_DRAM_CHANNEL + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI PMC1/PMC0 +SP [MFLOP/s] 1.0E-06*(PMC2)/time +Memory bandwidth [MBytes/s] 1.0E-06*(DFC0+DFC1)*64.0/time +Memory data volume [GBytes] 1.0E-09*(DFC0+DFC1)*64.0 +Operational intensity PMC2/((DFC0+DFC1)*64.0) + +LONG +Formulas: +DP [MFLOP/s] = 1.0E-06*(RETIRED_SSE_AVX_FLOPS_DOUBLE_ALL)/time +Memory bandwidth [MBytes/s] = 1.0E-06*(DATA_FROM_LOCAL_DRAM_CHANNEL+DATA_TO_LOCAL_DRAM_CHANNEL)*64.0/runtime +Memory data volume [GBytes] = 1.0E-09*(DATA_FROM_LOCAL_DRAM_CHANNEL+DATA_TO_LOCAL_DRAM_CHANNEL)*64.0 +Operational intensity = RETIRED_SSE_AVX_FLOPS_SINGLE_ALL/((DATA_FROM_LOCAL_DRAM_CHANNEL+DATA_TO_LOCAL_DRAM_CHANNEL)*64.0) +- +Profiling group to measure memory bandwidth drawn by all cores of a socket. +Since this group is based on Uncore events it is only possible to measure on a +per socket base. +The group provides almost accurate results for the total bandwidth and data volume. +AMD describes this metric as "approximate" in the documentation for AMD Rome. + +Be aware that despite the events imply a traffic direction (FROM and TO), the events +cannot be used to differentiate between read and write traffic. The events will be +renamed to avoid that confusion in the future. + diff --git a/collectors/likwid/groups/zen/NUMA.txt b/collectors/likwid/groups/zen/NUMA.txt new file mode 100644 index 0000000..19ccdc1 --- /dev/null +++ b/collectors/likwid/groups/zen/NUMA.txt @@ -0,0 +1,35 @@ +SHORT L2 cache bandwidth in MBytes/s (experimental) + +EVENTSET +FIXC1 ACTUAL_CPU_CLOCK +FIXC2 MAX_CPU_CLOCK +PMC0 DATA_CACHE_REFILLS_LOCAL_ALL +PMC1 DATA_CACHE_REFILLS_REMOTE_ALL +PMC2 HWPREF_DATA_CACHE_FILLS_LOCAL_ALL +PMC3 HWPREF_DATA_CACHE_FILLS_REMOTE_ALL + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI PMC1/PMC0 +Local bandwidth [MBytes/s] 1.0E-06*(PMC0+PMC2)*64.0/time +Local data volume [GBytes] 1.0E-09*(PMC0+PMC2)*64.0 +Remote bandwidth [MBytes/s] 1.0E-06*(PMC1+PMC3)*64.0/time +Remote data volume [GBytes] 1.0E-09*(PMC1+PMC3)*64.0 +Total bandwidth [MBytes/s] 1.0E-06*(PMC0+PMC2+PMC1+PMC3)*64.0/time +Total data volume [GBytes] 1.0E-09*(PMC0+PMC2+PMC1+PMC3)*64.0 + +LONG +Formulas: +Local bandwidth [MBytes/s] = 1.0E-06*(DATA_CACHE_REFILLS_LOCAL_ALL+HWPREF_DATA_CACHE_FILLS_LOCAL_ALL)*64.0/time +Local data volume [GBytes] = 1.0E-09*(DATA_CACHE_REFILLS_LOCAL_ALL+HWPREF_DATA_CACHE_FILLS_LOCAL_ALL)*64.0 +Remote bandwidth [MBytes/s] = 1.0E-06*(DATA_CACHE_REFILLS_REMOTE_ALL+HWPREF_DATA_CACHE_FILLS_REMOTE_ALL)*64.0/time +Remote data volume [GBytes] = 1.0E-09*(DATA_CACHE_REFILLS_REMOTE_ALL+HWPREF_DATA_CACHE_FILLS_REMOTE_ALL)*64.0 +Total bandwidth [MBytes/s] = 1.0E-06*(DATA_CACHE_REFILLS_LOCAL_ALL+HWPREF_DATA_CACHE_FILLS_LOCAL_ALL+DATA_CACHE_REFILLS_REMOTE_ALL+HWPREF_DATA_CACHE_FILLS_REMOTE_ALL)*64.0/time +Total data volume [GBytes] = 1.0E-09*(DATA_CACHE_REFILLS_LOCAL_ALL+HWPREF_DATA_CACHE_FILLS_LOCAL_ALL+DATA_CACHE_REFILLS_REMOTE_ALL+HWPREF_DATA_CACHE_FILLS_REMOTE_ALL)*64.0 +- +Profiling group to measure NUMA traffic. The data sources range from +local L2, CCX and memory for the local metrics and remote CCX and memory +for the remote metrics. There are also events that measure the software +prefetches from local and remote domain but AMD Zen provides only 4 counters. diff --git a/collectors/likwid/groups/zen/TLB.txt b/collectors/likwid/groups/zen/TLB.txt new file mode 100644 index 0000000..510284b --- /dev/null +++ b/collectors/likwid/groups/zen/TLB.txt @@ -0,0 +1,39 @@ +SHORT TLB miss rate/ratio + +EVENTSET +FIXC1 ACTUAL_CPU_CLOCK +FIXC2 MAX_CPU_CLOCK +PMC0 RETIRED_INSTRUCTIONS +PMC1 DATA_CACHE_ACCESSES +PMC2 L1_DTLB_MISS_ANY_L2_HIT +PMC3 L1_DTLB_MISS_ANY_L2_MISS + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/PMC0 +L1 DTLB request rate PMC1/PMC0 +L1 DTLB miss rate (PMC2+PMC3)/PMC0 +L1 DTLB miss ratio (PMC2+PMC3)/PMC1 +L2 DTLB request rate (PMC2+PMC3)/PMC0 +L2 DTLB miss rate PMC3/PMC0 +L2 DTLB miss ratio PMC3/(PMC2+PMC3) + + +LONG +Formulas: +L1 DTLB request rate = DATA_CACHE_ACCESSES / RETIRED_INSTRUCTIONS +L1 DTLB miss rate = (L1_DTLB_MISS_ANY_L2_HIT+L1_DTLB_MISS_ANY_L2_MISS)/RETIRED_INSTRUCTIONS +L1 DTLB miss ratio = (L1_DTLB_MISS_ANY_L2_HIT+L1_DTLB_MISS_ANY_L2_MISS)/DATA_CACHE_ACCESSES +L2 DTLB request rate = (L1_DTLB_MISS_ANY_L2_HIT+L1_DTLB_MISS_ANY_L2_MISS)/RETIRED_INSTRUCTIONS +L2 DTLB miss rate = L1_DTLB_MISS_ANY_L2_MISS / RETIRED_INSTRUCTIONS +L2 DTLB miss ratio = L1_DTLB_MISS_ANY_L2_MISS / (L1_DTLB_MISS_ANY_L2_HIT+L1_DTLB_MISS_ANY_L2_MISS) +- +L1 DTLB request rate tells you how data intensive your code is +or how many data accesses you have on average per instruction. +The DTLB miss rate gives a measure how often a TLB miss occurred +per instruction. And finally L1 DTLB miss ratio tells you how many +of your memory references required caused a TLB miss on average. +NOTE: The L2 metrics are only relevant if L2 DTLB request rate is +equal to the L1 DTLB miss rate! diff --git a/collectors/likwid/groups/zen2/BRANCH.txt b/collectors/likwid/groups/zen2/BRANCH.txt new file mode 100644 index 0000000..dbaf07f --- /dev/null +++ b/collectors/likwid/groups/zen2/BRANCH.txt @@ -0,0 +1,32 @@ +SHORT Branch prediction miss rate/ratio + +EVENTSET +FIXC1 ACTUAL_CPU_CLOCK +FIXC2 MAX_CPU_CLOCK +PMC0 RETIRED_INSTRUCTIONS +PMC1 CPU_CLOCKS_UNHALTED +PMC2 RETIRED_BRANCH_INSTR +PMC3 RETIRED_MISP_BRANCH_INSTR + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI PMC1/PMC0 +Branch rate PMC2/PMC0 +Branch misprediction rate PMC3/PMC0 +Branch misprediction ratio PMC3/PMC2 +Instructions per branch PMC0/PMC2 + +LONG +Formulas: +Branch rate = RETIRED_BRANCH_INSTR/RETIRED_INSTRUCTIONS +Branch misprediction rate = RETIRED_MISP_BRANCH_INSTR/RETIRED_INSTRUCTIONS +Branch misprediction ratio = RETIRED_MISP_BRANCH_INSTR/RETIRED_BRANCH_INSTR +Instructions per branch = RETIRED_INSTRUCTIONS/RETIRED_BRANCH_INSTR +- +The rates state how often on average a branch or a mispredicted branch occurred +per instruction retired in total. The branch misprediction ratio sets directly +into relation what ratio of all branch instruction where mispredicted. +Instructions per branch is 1/branch rate. + diff --git a/collectors/likwid/groups/zen2/CACHE.txt b/collectors/likwid/groups/zen2/CACHE.txt new file mode 100644 index 0000000..b773e5a --- /dev/null +++ b/collectors/likwid/groups/zen2/CACHE.txt @@ -0,0 +1,39 @@ +SHORT Data cache miss rate/ratio + +EVENTSET +FIXC1 ACTUAL_CPU_CLOCK +FIXC2 MAX_CPU_CLOCK +PMC0 RETIRED_INSTRUCTIONS +PMC1 CPU_CLOCKS_UNHALTED +PMC2 DATA_CACHE_ACCESSES +PMC3 DATA_CACHE_REFILLS_ALL + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI PMC1/PMC0 +data cache requests PMC2 +data cache request rate PMC2/PMC0 +data cache misses PMC3 +data cache miss rate PMC3/PMC0 +data cache miss ratio PMC3/PMC2 + +LONG +Formulas: +data cache requests = DATA_CACHE_ACCESSES +data cache request rate = DATA_CACHE_ACCESSES / RETIRED_INSTRUCTIONS +data cache misses = DATA_CACHE_REFILLS_ALL +data cache miss rate = DATA_CACHE_REFILLS_ALL / RETIRED_INSTRUCTIONS +data cache miss ratio = DATA_CACHE_REFILLS_ALL / DATA_CACHE_ACCESSES +- +This group measures the locality of your data accesses with regard to the +L1 cache. Data cache request rate tells you how data intensive your code is +or how many data accesses you have on average per instruction. +The data cache miss rate gives a measure how often it was necessary to get +cache lines from higher levels of the memory hierarchy. And finally +data cache miss ratio tells you how many of your memory references required +a cache line to be loaded from a higher level. While the# data cache miss rate +might be given by your algorithm you should try to get data cache miss ratio +as low as possible by increasing your cache reuse. + diff --git a/collectors/likwid/groups/zen2/CPI.txt b/collectors/likwid/groups/zen2/CPI.txt new file mode 100644 index 0000000..23e4f8c --- /dev/null +++ b/collectors/likwid/groups/zen2/CPI.txt @@ -0,0 +1,30 @@ +SHORT Cycles per instruction + +EVENTSET +FIXC1 ACTUAL_CPU_CLOCK +FIXC2 MAX_CPU_CLOCK +PMC0 RETIRED_INSTRUCTIONS +PMC1 CPU_CLOCKS_UNHALTED +PMC2 RETIRED_UOPS + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] PMC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI PMC1/PMC0 +CPI (based on uops) PMC1/PMC2 +IPC PMC0/PMC1 + + +LONG +Formulas: +CPI = CPU_CLOCKS_UNHALTED/RETIRED_INSTRUCTIONS +CPI (based on uops) = CPU_CLOCKS_UNHALTED/RETIRED_UOPS +IPC = RETIRED_INSTRUCTIONS/CPU_CLOCKS_UNHALTED +- +This group measures how efficient the processor works with +regard to instruction throughput. Also important as a standalone +metric is RETIRED_INSTRUCTIONS as it tells you how many instruction +you need to execute for a task. An optimization might show very +low CPI values but execute many more instruction for it. + diff --git a/collectors/likwid/groups/zen2/DATA.txt b/collectors/likwid/groups/zen2/DATA.txt new file mode 100644 index 0000000..e061b90 --- /dev/null +++ b/collectors/likwid/groups/zen2/DATA.txt @@ -0,0 +1,23 @@ +SHORT Load to store ratio + +EVENTSET +FIXC1 ACTUAL_CPU_CLOCK +FIXC2 MAX_CPU_CLOCK +PMC0 RETIRED_INSTRUCTIONS +PMC1 CPU_CLOCKS_UNHALTED +PMC2 LS_DISPATCH_LOADS +PMC3 LS_DISPATCH_STORES + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI PMC1/PMC0 +Load to store ratio PMC2/PMC3 + +LONG +Formulas: +Load to store ratio = LS_DISPATCH_LOADS/LS_DISPATCH_STORES +- +This is a simple metric to determine your load to store ratio. + diff --git a/collectors/likwid/groups/zen2/DIVIDE.txt b/collectors/likwid/groups/zen2/DIVIDE.txt new file mode 100644 index 0000000..13d629b --- /dev/null +++ b/collectors/likwid/groups/zen2/DIVIDE.txt @@ -0,0 +1,25 @@ +SHORT Divide unit information + +EVENTSET +FIXC1 ACTUAL_CPU_CLOCK +FIXC2 MAX_CPU_CLOCK +PMC0 RETIRED_INSTRUCTIONS +PMC1 CPU_CLOCKS_UNHALTED +PMC2 DIV_OP_COUNT +PMC3 DIV_BUSY_CYCLES + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI PMC1/PMC0 +Number of divide ops PMC2 +Avg. divide unit usage duration PMC3/PMC2 + +LONG +Formulas: +Number of divide ops = DIV_OP_COUNT +Avg. divide unit usage duration = DIV_BUSY_CYCLES/DIV_OP_COUNT +-- +This performance group measures the average latency of divide operations diff --git a/collectors/likwid/groups/zen2/ENERGY.txt b/collectors/likwid/groups/zen2/ENERGY.txt new file mode 100644 index 0000000..f58c5b1 --- /dev/null +++ b/collectors/likwid/groups/zen2/ENERGY.txt @@ -0,0 +1,32 @@ +SHORT Power and Energy consumption + +EVENTSET +FIXC1 ACTUAL_CPU_CLOCK +FIXC2 MAX_CPU_CLOCK +PMC0 RETIRED_INSTRUCTIONS +PMC1 CPU_CLOCKS_UNHALTED +PWR0 RAPL_CORE_ENERGY +PWR1 RAPL_PKG_ENERGY + + + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI PMC1/PMC0 +Energy Core [J] PWR0 +Power Core [W] PWR0/time +Energy PKG [J] PWR1 +Power PKG [W] PWR1/time + +LONG +Formulas: +Power Core [W] = RAPL_CORE_ENERGY/time +Power PKG [W] = RAPL_PKG_ENERGY/time +- +Ryzen implements the RAPL interface previously introduced by Intel. +This interface enables to monitor the consumed energy on the core and package +domain. +It is not documented by AMD which parts of the CPU are in which domain. + diff --git a/collectors/likwid/groups/zen2/FLOPS_DP.txt b/collectors/likwid/groups/zen2/FLOPS_DP.txt new file mode 100644 index 0000000..740acb9 --- /dev/null +++ b/collectors/likwid/groups/zen2/FLOPS_DP.txt @@ -0,0 +1,28 @@ +SHORT Double Precision MFLOP/s + +EVENTSET +FIXC1 ACTUAL_CPU_CLOCK +FIXC2 MAX_CPU_CLOCK +PMC0 RETIRED_INSTRUCTIONS +PMC1 CPU_CLOCKS_UNHALTED +PMC2 RETIRED_SSE_AVX_FLOPS_ALL +PMC3 MERGE + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI PMC1/PMC0 +DP [MFLOP/s] 1.0E-06*(PMC2)/time + +LONG +Formulas: +CPI = CPU_CLOCKS_UNHALTED/RETIRED_INSTRUCTIONS +DP [MFLOP/s] = 1.0E-06*(RETIRED_SSE_AVX_FLOPS_ALL)/time +- +Profiling group to measure (double-precisision) FLOP rate. The event might +have a higher per-cycle increment than 15, so the MERGE event is required. In +contrast to AMD Zen, the Zen2 microarchitecture does not provide events to +differentiate between single- and double-precision. + + diff --git a/collectors/likwid/groups/zen2/FLOPS_SP.txt b/collectors/likwid/groups/zen2/FLOPS_SP.txt new file mode 100644 index 0000000..0d25aeb --- /dev/null +++ b/collectors/likwid/groups/zen2/FLOPS_SP.txt @@ -0,0 +1,28 @@ +SHORT Single Precision MFLOP/s + +EVENTSET +FIXC1 ACTUAL_CPU_CLOCK +FIXC2 MAX_CPU_CLOCK +PMC0 RETIRED_INSTRUCTIONS +PMC1 CPU_CLOCKS_UNHALTED +PMC2 RETIRED_SSE_AVX_FLOPS_ALL +PMC3 MERGE + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI PMC1/PMC0 +SP [MFLOP/s] 1.0E-06*(PMC2)/time + +LONG +Formulas: +CPI = CPU_CLOCKS_UNHALTED/RETIRED_INSTRUCTIONS +SP [MFLOP/s] = 1.0E-06*(RETIRED_SSE_AVX_FLOPS_ALL)/time +- +Profiling group to measure (single-precisision) FLOP rate. The event might +have a higher per-cycle increment than 15, so the MERGE event is required. In +contrast to AMD Zen, the Zen2 microarchitecture does not provide events to +differentiate between single- and double-precision. + + diff --git a/collectors/likwid/groups/zen2/ICACHE.txt b/collectors/likwid/groups/zen2/ICACHE.txt new file mode 100644 index 0000000..f98c28a --- /dev/null +++ b/collectors/likwid/groups/zen2/ICACHE.txt @@ -0,0 +1,28 @@ +SHORT Instruction cache miss rate/ratio + +EVENTSET +FIXC1 ACTUAL_CPU_CLOCK +FIXC2 MAX_CPU_CLOCK +PMC0 RETIRED_INSTRUCTIONS +PMC1 ICACHE_FETCHES +PMC2 ICACHE_L2_REFILLS +PMC3 ICACHE_SYSTEM_REFILLS + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/PMC0 +L1I request rate PMC1/PMC0 +L1I miss rate (PMC2+PMC3)/PMC0 +L1I miss ratio (PMC2+PMC3)/PMC1 + +LONG +Formulas: +L1I request rate = ICACHE_FETCHES / RETIRED_INSTRUCTIONS +L1I miss rate = (ICACHE_L2_REFILLS + ICACHE_SYSTEM_REFILLS)/RETIRED_INSTRUCTIONS +L1I miss ratio = (ICACHE_L2_REFILLS + ICACHE_SYSTEM_REFILLS)/ICACHE_FETCHES +- +This group measures the locality of your instruction code with regard to the +L1 I-Cache. + diff --git a/collectors/likwid/groups/zen2/L2.txt b/collectors/likwid/groups/zen2/L2.txt new file mode 100644 index 0000000..420e34d --- /dev/null +++ b/collectors/likwid/groups/zen2/L2.txt @@ -0,0 +1,28 @@ +SHORT L2 cache bandwidth in MBytes/s (experimental) + +EVENTSET +FIXC1 ACTUAL_CPU_CLOCK +FIXC2 MAX_CPU_CLOCK +PMC0 RETIRED_INSTRUCTIONS +PMC1 CPU_CLOCKS_UNHALTED +PMC3 REQUESTS_TO_L2_GRP1_ALL_NO_PF + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI PMC1/PMC0 +L2D load bandwidth [MBytes/s] 1.0E-06*PMC3*64.0/time +L2D load data volume [GBytes] 1.0E-09*PMC3*64.0 +L2 bandwidth [MBytes/s] 1.0E-06*(PMC3)*64.0/time +L2 data volume [GBytes] 1.0E-09*(PMC3)*64.0 + +LONG +Formulas: +L2D load bandwidth [MBytes/s] = 1.0E-06*REQUESTS_TO_L2_GRP1_ALL_NO_PF*64.0/time +L2D load data volume [GBytes] = 1.0E-09*REQUESTS_TO_L2_GRP1_ALL_NO_PF*64.0 +L2 bandwidth [MBytes/s] = 1.0E-06*(REQUESTS_TO_L2_GRP1_ALL_NO_PF)*64/time +L2 data volume [GBytes] = 1.0E-09*(REQUESTS_TO_L2_GRP1_ALL_NO_PF)*64 +- +Profiling group to measure L2 cache bandwidth. There is no way to measure +the store traffic between L1 and L2. diff --git a/collectors/likwid/groups/zen2/L3.txt b/collectors/likwid/groups/zen2/L3.txt new file mode 100644 index 0000000..6fe808a --- /dev/null +++ b/collectors/likwid/groups/zen2/L3.txt @@ -0,0 +1,32 @@ +SHORT L3 cache bandwidth in MBytes/s + +EVENTSET +FIXC1 ACTUAL_CPU_CLOCK +FIXC2 MAX_CPU_CLOCK +PMC0 RETIRED_INSTRUCTIONS +PMC1 CPU_CLOCKS_UNHALTED +CPMC0 L3_ACCESS +CPMC1 L3_MISS + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI PMC1/PMC0 +L3 access bandwidth [MBytes/s] 1.0E-06*CPMC0*64.0/time +L3 access data volume [GBytes] 1.0E-09*CPMC0*64.0 +L3 access rate [%] (CPMC0/PMC0)*100.0 +L3 miss rate [%] (CPMC1/PMC0)*100.0 +L3 miss ratio [%] (CPMC1/CPMC0)*100.0 + +LONG +Formulas: +L3 access bandwidth [MBytes/s] = 1.0E-06*L3_ACCESS*64.0/time +L3 access data volume [GBytes] = 1.0E-09*L3_ACCESS*64.0 +L3 access rate [%] = (L3_ACCESS/RETIRED_INSTRUCTIONS)*100 +L3 miss rate [%] = (L3_MISS/RETIRED_INSTRUCTIONS)*100 +L3 miss ratio [%]= (L3_MISS/L3_ACCESS)*100 +- +Profiling group to measure L3 cache bandwidth. There is no way to measure +the store traffic between L2 and L3. The only two published L3 events are +L3_ACCESS and L3_MISS. diff --git a/collectors/likwid/groups/zen2/MEM.txt b/collectors/likwid/groups/zen2/MEM.txt new file mode 100644 index 0000000..c589640 --- /dev/null +++ b/collectors/likwid/groups/zen2/MEM.txt @@ -0,0 +1,35 @@ +SHORT Main memory bandwidth in MBytes/s (experimental) + +EVENTSET +FIXC1 ACTUAL_CPU_CLOCK +FIXC2 MAX_CPU_CLOCK +PMC0 RETIRED_INSTRUCTIONS +PMC1 CPU_CLOCKS_UNHALTED +DFC0 DATA_FROM_LOCAL_DRAM_CHANNEL +DFC1 DATA_TO_LOCAL_DRAM_CHANNEL + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI PMC1/PMC0 +Memory bandwidth [MBytes/s] 1.0E-06*(DFC0+DFC1)*(4.0/num_numadomains)*64.0/time +Memory data volume [GBytes] 1.0E-09*(DFC0+DFC1)*(4.0/num_numadomains)*64.0 + +LONG +Formulas: +Memory bandwidth [MBytes/s] = 4.0E-06*(DATA_FROM_LOCAL_DRAM_CHANNEL+DATA_TO_LOCAL_DRAM_CHANNEL)*(4.0/num_numadomains)*64.0/runtime +Memory data volume [GBytes] = 4.0E-09*(DATA_FROM_LOCAL_DRAM_CHANNEL+DATA_TO_LOCAL_DRAM_CHANNEL)*(4.0/num_numadomains)*64.0 +- +Profiling group to measure memory bandwidth drawn by all cores of a socket. +Since this group is based on Uncore events it is only possible to measure on a +per socket base. +The group provides almost accurate results for the total bandwidth +and data volume. +The metric formulas contain a correction factor of (4.0/num_numadomains) to +return the value for all 4 memory controllers in NPS1 mode. This is probably +a work-around. Requested info from AMD but no answer. + +Be aware that despite the events imply a traffic direction (FROM and TO), the events +cannot be used to differentiate between read and write traffic. The events will be +renamed to avoid that confusion in the future. diff --git a/collectors/likwid/groups/zen2/NUMA.txt b/collectors/likwid/groups/zen2/NUMA.txt new file mode 100644 index 0000000..6cb881a --- /dev/null +++ b/collectors/likwid/groups/zen2/NUMA.txt @@ -0,0 +1,35 @@ +SHORT Local and remote memory accesses (experimental) + +EVENTSET +FIXC1 ACTUAL_CPU_CLOCK +FIXC2 MAX_CPU_CLOCK +PMC0 DATA_CACHE_REFILLS_LOCAL_ALL +PMC1 DATA_CACHE_REFILLS_REMOTE_ALL +PMC2 HWPREF_DATA_CACHE_FILLS_LOCAL_ALL +PMC3 HWPREF_DATA_CACHE_FILLS_REMOTE_ALL + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI PMC1/PMC0 +Local bandwidth [MBytes/s] 1.0E-06*(PMC0+PMC2)*64.0/time +Local data volume [GBytes] 1.0E-09*(PMC0+PMC2)*64.0 +Remote bandwidth [MBytes/s] 1.0E-06*(PMC1+PMC3)*64.0/time +Remote data volume [GBytes] 1.0E-09*(PMC1+PMC3)*64.0 +Total bandwidth [MBytes/s] 1.0E-06*(PMC0+PMC2+PMC1+PMC3)*64.0/time +Total data volume [GBytes] 1.0E-09*(PMC0+PMC2+PMC1+PMC3)*64.0 + +LONG +Formulas: +Local bandwidth [MBytes/s] = 1.0E-06*(DATA_CACHE_REFILLS_LOCAL_ALL+HWPREF_DATA_CACHE_FILLS_LOCAL_ALL)*64.0/time +Local data volume [GBytes] = 1.0E-09*(DATA_CACHE_REFILLS_LOCAL_ALL+HWPREF_DATA_CACHE_FILLS_LOCAL_ALL)*64.0 +Remote bandwidth [MBytes/s] = 1.0E-06*(DATA_CACHE_REFILLS_REMOTE_ALL+HWPREF_DATA_CACHE_FILLS_REMOTE_ALL)*64.0/time +Remote data volume [GBytes] = 1.0E-09*(DATA_CACHE_REFILLS_REMOTE_ALL+HWPREF_DATA_CACHE_FILLS_REMOTE_ALL)*64.0 +Total bandwidth [MBytes/s] = 1.0E-06*(DATA_CACHE_REFILLS_LOCAL_ALL+HWPREF_DATA_CACHE_FILLS_LOCAL_ALL+DATA_CACHE_REFILLS_REMOTE_ALL+HWPREF_DATA_CACHE_FILLS_REMOTE_ALL)*64.0/time +Total data volume [GBytes] = 1.0E-09*(DATA_CACHE_REFILLS_LOCAL_ALL+HWPREF_DATA_CACHE_FILLS_LOCAL_ALL+DATA_CACHE_REFILLS_REMOTE_ALL+HWPREF_DATA_CACHE_FILLS_REMOTE_ALL)*64.0 +- +Profiling group to measure NUMA traffic. The data sources range from +local L2, CCX and memory for the local metrics and remote CCX and memory +for the remote metrics. There are also events that measure the software +prefetches from local and remote domain but AMD Zen provides only 4 counters. diff --git a/collectors/likwid/groups/zen2/TLB.txt b/collectors/likwid/groups/zen2/TLB.txt new file mode 100644 index 0000000..510284b --- /dev/null +++ b/collectors/likwid/groups/zen2/TLB.txt @@ -0,0 +1,39 @@ +SHORT TLB miss rate/ratio + +EVENTSET +FIXC1 ACTUAL_CPU_CLOCK +FIXC2 MAX_CPU_CLOCK +PMC0 RETIRED_INSTRUCTIONS +PMC1 DATA_CACHE_ACCESSES +PMC2 L1_DTLB_MISS_ANY_L2_HIT +PMC3 L1_DTLB_MISS_ANY_L2_MISS + +METRICS +Runtime (RDTSC) [s] time +Runtime unhalted [s] FIXC1*inverseClock +Clock [MHz] 1.E-06*(FIXC1/FIXC2)/inverseClock +CPI FIXC1/PMC0 +L1 DTLB request rate PMC1/PMC0 +L1 DTLB miss rate (PMC2+PMC3)/PMC0 +L1 DTLB miss ratio (PMC2+PMC3)/PMC1 +L2 DTLB request rate (PMC2+PMC3)/PMC0 +L2 DTLB miss rate PMC3/PMC0 +L2 DTLB miss ratio PMC3/(PMC2+PMC3) + + +LONG +Formulas: +L1 DTLB request rate = DATA_CACHE_ACCESSES / RETIRED_INSTRUCTIONS +L1 DTLB miss rate = (L1_DTLB_MISS_ANY_L2_HIT+L1_DTLB_MISS_ANY_L2_MISS)/RETIRED_INSTRUCTIONS +L1 DTLB miss ratio = (L1_DTLB_MISS_ANY_L2_HIT+L1_DTLB_MISS_ANY_L2_MISS)/DATA_CACHE_ACCESSES +L2 DTLB request rate = (L1_DTLB_MISS_ANY_L2_HIT+L1_DTLB_MISS_ANY_L2_MISS)/RETIRED_INSTRUCTIONS +L2 DTLB miss rate = L1_DTLB_MISS_ANY_L2_MISS / RETIRED_INSTRUCTIONS +L2 DTLB miss ratio = L1_DTLB_MISS_ANY_L2_MISS / (L1_DTLB_MISS_ANY_L2_HIT+L1_DTLB_MISS_ANY_L2_MISS) +- +L1 DTLB request rate tells you how data intensive your code is +or how many data accesses you have on average per instruction. +The DTLB miss rate gives a measure how often a TLB miss occurred +per instruction. And finally L1 DTLB miss ratio tells you how many +of your memory references required caused a TLB miss on average. +NOTE: The L2 metrics are only relevant if L2 DTLB request rate is +equal to the L1 DTLB miss rate! diff --git a/collectors/likwid/groups/zen3/.empty b/collectors/likwid/groups/zen3/.empty new file mode 100644 index 0000000..5e965d1 --- /dev/null +++ b/collectors/likwid/groups/zen3/.empty @@ -0,0 +1 @@ +There is currently no public documentation for AMD Zen3. This folder is just a placeholder for future performance groups. diff --git a/collectors/likwid/liblikwid-hwloc.a b/collectors/likwid/liblikwid-hwloc.a new file mode 100644 index 0000000000000000000000000000000000000000..09feadd188f525bc46b8564b9c0e5a7537e5bc99 GIT binary patch literal 600536 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⩔s~Tjn^|e+$d~H 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≫`APXyH~tHTpW8J6((?TA;_-hFDF-k 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�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νcY+FYbV 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

a^>->@zoka}V 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