source: trunk/sys/libmemc/memc_perfmon.c @ 351

Last change on this file since 351 was 1, checked in by alain, 8 years ago

First import

File size: 5.6 KB
Line 
1/*
2 * memc_perfmon.c - TSAR MEMC Performance Monitor
3 *
4 * Copyright (c) 2013 UPMC Sorbonne Universites
5 *
6 * This file is part of ALMOS.
7 *
8 * ALMOS is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; version 2.0 of the License.
11 *
12 * ALMOS is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with ALMOS; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22#include <stdint.h>
23#include <fcntl.h>
24#include <stdio.h>
25#include <unistd.h>
26#include <stdlib.h>
27#include "memc_perfmon.h"
28
29#define MEMC_REGS_NR   27
30
31struct memc_regs_s
32{
33        const char *name;
34        const char *info;
35};
36
37const struct memc_regs_s memc_regs[MEMC_REGS_NR] = {
38        {"MEMC_RD_LOCAL", "Number of local read commands (instruction, data, TLB)"},
39        {"MEMC_RD_REMOTE", "Number of remote read commands"},
40        {"MEMC_RD_COST", "Cost (flits x distance) recieved read commands"},
41        {"MEMC_WR_LOCAL", "Number of local write flits"},
42        {"MEMC_WR_REMOTE", "Number of remote write flits"},
43        {"MEMC_WR_COST", "Cost (flits x distance) of recieved write commands"},
44        {"MEMC_LL_LOCAL", "Number of local linked-load commands"},
45        {"MEMC_LL_REMOTE", "Number of remote linked-load commands"},
46        {"MEMC_LL_COST", "Cost (flits x distance) of recieved linked-load commands"},
47        {"MEMC_SC_LOCAL", "Number of local store-conditional commands"},
48        {"MEMC_SC_REMOTE", "Number of remote store-conditional commands"},
49        {"MEMC_SC_COST", "Cost (flits x distance) of recieved store-conditional commands"},
50        {"MEMC_CS_LOCAL", "Number of local CAS commands"},
51        {"MEMC_CS_REMOTE", "Number of remote CAS commands"},
52        {"MEMC_CS_COST", "Cost (flits x distance) of recieved CAS commands"},
53        {"MEMC_MUPDT_LOCAL", "Number of local multi-update commands"},
54        {"MEMC_MUPDT_REMOTE", "Number of remote multi-update commands"},
55        {"MEMC_MUPDT_COST", "Cost (flits x distance) of issued multi-update commands"},
56        {"MEMC_MINVL_LOCAL", "Number of local multi-invalidate commands"},
57        {"MEMC_MINVL_REMOTE", "Number of remote multi-invalidate commands"},
58        {"MEMC_MINVL_COST", "Cost (flits x distance) of issued multi-invalidate commands"},
59        {"MEMC_CLNUP_LOCAL", "Number of local clean-up commands"},
60        {"MEMC_CLNUP_REMOTE", "Number of remote clean-up commands"},
61        {"MEMC_CLNUP_COST", "Cost (flits x distance) of issued clean-up commands"},
62        {"MEMC_MUPDT_TOTAL", "Total number of multi-update commands"},
63        {"MEMC_MINVL_TOTAL", "Total number of multi-invalidate commands"},
64        {"MEMC_BINVL_TOTAL", "Total number of broadcast-invalidate commands"}};
65
66struct memc_context_s
67{
68        uint32_t start_tbl[MEMC_REGS_NR];
69        uint32_t stop_tbl[MEMC_REGS_NR];
70        int fd;
71};
72
73void memc_perfmon_destroy(struct memc_perfmon_s *perfmon)
74{
75        struct memc_context_s *ctx;
76        int i;
77
78        for(i = 0; i < perfmon->count; i++)
79        {
80                ctx = &perfmon->tbl[i];
81
82                if(ctx->fd != -1)
83                        close(ctx->fd);
84        }
85
86        perfmon->count = 0;
87        free(perfmon->tbl);
88}
89
90int memc_perfmon_init(struct memc_perfmon_s *perfmon)
91{
92        struct memc_context_s *ctx;
93        int fd,count,i,j;
94        char name[16];
95
96        count = sysconf(_SC_NCLUSTERS_ONLN);
97        count = (count < 1) ? 1 : count;
98 
99        perfmon->tbl = valloc(sizeof(*ctx) * count);
100
101        if(perfmon->tbl == NULL)
102                return -1;
103
104        for(i = 0; i < count; i++)
105        {
106                sprintf(&name[0], "/DEV/MEMC%d", i);
107                fd = open(&name[0], O_RDONLY, 0);
108
109                perfmon->tbl[i].fd = fd;
110
111                if(fd == -1)
112                        break;
113               
114                for(j = 0; j < MEMC_REGS_NR; j++)
115                {
116                        perfmon->tbl[i].start_tbl[j] = 0;
117                        perfmon->tbl[i].stop_tbl[j]  = 0;
118                }
119        }
120
121        perfmon->count = i;
122
123        if(fd == -1)
124        {
125                memc_perfmon_destroy(perfmon);
126                return -2;
127        }
128
129        return 0;
130}
131
132int memc_perfmon_start(struct memc_perfmon_s *perfmon)
133{
134        struct memc_context_s *ctx;
135        int count, size, i;
136
137        for(i = 0; i < perfmon->count; i++)
138        {
139                ctx   = &perfmon->tbl[i];
140                size  = sizeof(ctx->start_tbl) - 12; /* last three registers seem to be bugious */
141                count = read(ctx->fd, &ctx->start_tbl[0], size);
142
143                if(count != size)
144                {
145                        fprintf(stderr, 
146                                "Warning: %s - memc%d registers were"
147                                "not read entirely\n", __FUNCTION__, i);
148                }
149        }
150
151        return 0;
152}
153
154int memc_perfmon_stop(struct memc_perfmon_s *perfmon)
155{
156        struct memc_context_s *ctx;
157        int count, size, i;
158
159        for(i = 0; i < perfmon->count; i++)
160        {
161                ctx   = &perfmon->tbl[i];
162                size  = sizeof(ctx->stop_tbl) - 12; /* last three registers seem to be bugious */
163                count = read(ctx->fd, &ctx->stop_tbl[0], size);
164
165                if(count != size)
166                {
167                        fprintf(stderr, 
168                                "Warning: %s - memc%d registers were"
169                                "not read entirely\n", __FUNCTION__, i);
170                }
171        }
172
173        return 0;
174}
175
176void memc_perfmon_print(struct memc_perfmon_s *perfmon)
177{
178        struct memc_context_s *ctx;
179        uint32_t value;
180        int i,j;
181
182        for(i = 0; i < perfmon->count; i++)
183        {
184                ctx = &perfmon->tbl[i];
185                printf("[MEMC%d]\n", i);
186
187                for(j = 0; j < MEMC_REGS_NR; j++)
188                {
189                        value = ctx->stop_tbl[j] - ctx->start_tbl[j];
190                        printf("\t[%d] %s\t = %u\n", j, memc_regs[j].name, value);
191                }
192        }
193}
194
195void memc_perfmon_dump(struct memc_perfmon_s *perfmon)
196{
197        struct memc_context_s *ctx;
198        uint32_t value;
199        int i,j;
200
201        for(i = 0; i < perfmon->count; i++)
202        {
203                ctx = &perfmon->tbl[i];
204                printf("[MEMC%d]\n\t[START]\n", i);
205
206                for(j = 0; j < MEMC_REGS_NR; j++)
207                        printf("\t\t[%d] %s\t = %u\n", j, memc_regs[j].name, ctx->start_tbl[j]);
208
209                printf("\t[STOP]\n");
210
211                for(j = 0; j < MEMC_REGS_NR; j++)
212                        printf("\t\t[%d] %s\t = %u\n", j, memc_regs[j].name, ctx->stop_tbl[j]);
213        }
214}
Note: See TracBrowser for help on using the repository browser.