source: trunk/modules/vci_profiler/caba/source/src/vci_profiler.cpp @ 258

Last change on this file since 258 was 258, checked in by almaless, 12 years ago

Introduce a vci profiler for TSAR direct network

File size: 13.2 KB
Line 
1/* -*- c++ -*-
2 *
3 * SOCLIB_LGPL_HEADER_BEGIN
4 *
5 * This file is part of SoCLib, GNU LGPLv2.1.
6 *
7 * SoCLib is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as published
9 * by the Free Software Foundation; version 2.1 of the License.
10 *
11 * SoCLib is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with SoCLib; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 * 02110-1301 USA
20 *
21 * SOCLIB_LGPL_HEADER_END
22 *
23 * Copyright (c) UPMC, Lip6
24 *         Ghassan Almaless <ghassan.almaless@lip6.fr>, 2011
25 *
26 * Maintainers: Ghassan
27 */
28
29#include "vci_profiler.h"
30#include <cstring>
31#include <iostream>
32#include "vci_buffers.h"
33#include <iostream>
34#include <iomanip>
35#include <cassert>
36#include <vector>
37
38namespace soclib {
39namespace caba {
40
41#define tmpl(...) template<typename vci_param, typename iss_t> __VA_ARGS__ VciProfiler<vci_param, iss_t>
42
43#define ABS(x) (((x) < 0) ? -(x) : (x))
44
45#define VCI_iRD_CMD             4
46#define VCI_iTLB_RD_CMD         5
47#define VCI_iTLB_LL_CMD         6
48#define VCI_iTLB_SC_CMD         7
49#define VCI_DTLB_RD_CMD         8
50#define VCI_DTLB_LL_CMD         9
51#define VCI_DTLB_SC_CMD         10
52
53#define _CMD_ITLB               0x1
54#define _CMD_DTLB               0x2   
55#define _CMD_USR                0x4
56
57static const char* vci_cmd_names[VCI_CMD_NR] = {"SC_CMD ", 
58                                                "RD_CMD ", 
59                                                "WR_CMD ", 
60                                                "LL_CMD ", 
61                                                "iRD_CMD",
62                                                "iTLB_RD_CMD",
63                                                "iTLB_LL_CMD",
64                                                "iTLB_SC_CMD",
65                                                "DTLB_RD_CMD",
66                                                "DTLB_LL_CMD",
67                                                "DTLB_SC_CMD"};
68
69tmpl(void)::print_stats()
70{
71    unsigned long local_cntr;
72    unsigned long total_cost;
73    unsigned long total_flits;
74    unsigned long total_rflits;
75    unsigned long total_estmtd_enrg;
76    std::ostream &output = m_l1->m_log;
77
78    if(m_period == 0)
79        return;
80   
81    total_cost        = 0;
82    total_flits       = 0;
83    total_rflits      = 0;
84    total_estmtd_enrg = 0;
85   
86    local_cntr = m_access_cntr - m_remote_cntr;
87   
88    output << name() << " Cycles: " << std::dec << m_tm_now << std::endl
89           << "Access_Rate  = " << (double)  m_access_cntr / m_cycles_cntr << std::endl
90           << "Remote_%     = " << (double)  m_remote_cntr / m_access_cntr << std::endl
91           << "LL_%         = " << (double)  m_cmd_tbl[vci_param::CMD_LOCKED_READ].trans / m_access_cntr << std::endl
92           << "SC_%         = " << (double)  m_cmd_tbl[vci_param::CMD_STORE_COND].trans  / m_access_cntr << std::endl;
93   
94    for(long i = 0; i < VCI_CMD_NR; i++)
95    {
96
97        local_cntr = m_cmd_tbl[i].distance * m_cmd_tbl[i].rflits;
98
99        output << vci_cmd_names[i] << " [" 
100               << m_cmd_tbl[i].trans << ", "
101               << m_cmd_tbl[i].remote << ", "
102               << m_cmd_tbl[i].trans - m_cmd_tbl[i].remote  << ", "
103               << m_cmd_tbl[i].cost << ", "
104               << m_cmd_tbl[i].rcost << ", "
105               << m_cmd_tbl[i].cost - m_cmd_tbl[i].rcost << ", "
106               << m_cmd_tbl[i].limit1 << ", "
107               << m_cmd_tbl[i].limit2 << ", "
108               << m_cmd_tbl[i].rmax_cost << ", "
109               << m_cmd_tbl[i].rmax_time << ", "
110               << m_cmd_tbl[i].lmax_cost << ", "
111               << m_cmd_tbl[i].lmax_time << ", "
112               << m_cmd_tbl[i].flits <<  ", " 
113               << m_cmd_tbl[i].rflits << ", " << std::hex
114               << m_cmd_tbl[i].raddr << ", " << std::dec
115               << m_cmd_tbl[i].distance << ","
116               << m_cmd_tbl[i].d1_limit << ","
117               << m_cmd_tbl[i].d2_limit << ","
118               << m_cmd_tbl[i].max_dist << ","
119               << local_cntr << "]" << std::endl;
120
121        total_cost        += m_cmd_tbl[i].cost;
122        total_flits       += m_cmd_tbl[i].flits;
123        total_rflits      += m_cmd_tbl[i].rflits;
124        total_estmtd_enrg += local_cntr;
125    }
126   
127    output << "Total_CMDs         = " << m_access_cntr << std::endl
128           << "Total_Cost         = " << total_cost << std::endl
129           << "Total_Flits        = " << total_flits << std::endl
130           << "Total_Remote_Flits = " << total_rflits << std::endl
131           << "Total_Estmtd_Enrg  = " << total_estmtd_enrg << std::endl;
132}
133
134tmpl(void)::clear_stats()
135{
136    memset(m_cmd_tbl, 0, sizeof(m_cmd_tbl));
137    m_access_cntr = 0;
138    m_remote_cntr = 0;
139    m_cycles_cntr = 0;
140}
141
142
143tmpl(void)::set_limits(unsigned long limit1, unsigned long limit2)
144{
145    m_limit1 = limit1;
146    m_limit2 = limit2;
147}
148
149tmpl(void)::set_L1_cache(VciCcVCacheWrapper2V1<vci_param, iss_t> *l1)
150{
151    m_l1 = l1;
152}
153
154
155tmpl()::VciProfiler(
156                  sc_core::sc_module_name insname,
157                  size_t index, 
158                  size_t x_id,
159                  size_t y_id,
160                  size_t x_width,
161                  size_t y_width,
162                  size_t addr_width)
163        : BaseModule(insname),
164      p_resetn("resetn"),
165      p_clk("clk"),
166      p_vci("vci")
167{
168    clear_stats();
169    m_index        = index;
170    m_x            = x_id;
171    m_y            = y_id;
172    m_xWidth       = x_width;
173    m_yWidth       = y_width;
174    m_width        = x_width + y_width;
175    m_bits         = addr_width;
176    m_tm_now       = 0;
177    m_tm_start     = 0;
178    m_isPending    = false;
179    m_isCMDPending = false;
180    m_isPeriod     = false;
181    m_isDebug      = false;
182    m_last_cmd     = 0;
183    m_limit1       = 0;
184    m_limit2       = 0;
185    m_d1_limit     = 0;
186    m_d2_limit     = 0;
187    m_period       = 0;
188    m_debug_cntr   = 0;
189    m_threshold    = 1000000;
190
191    char *ptr = getenv("TSAR_PROFILER_PERIOD");
192
193    if(ptr != NULL)
194        m_period = atol(ptr);
195
196    ptr = getenv("TSAR_PROFILER_THRESHOLD");
197
198    if(ptr != NULL)
199        m_threshold = atol(ptr);
200
201    ptr = getenv("TSAR_PROFILER_DEBUG");
202
203    if(ptr != NULL)
204        m_isDebug = (atol(ptr) != 0) ? true : false;
205
206    ptr = getenv("TSAR_PROFILER_LIMIT1");
207
208    if(ptr != NULL)
209        m_limit1 = atol(ptr);
210
211    ptr = getenv("TSAR_PROFILER_LIMIT2");
212
213    if(ptr != NULL)
214        m_limit2 = atol(ptr);
215
216    ptr = getenv("TSAR_PROFILER_D1_LIMIT");
217
218    if(ptr != NULL)
219        m_d1_limit = atol(ptr);
220
221    ptr = getenv("TSAR_PROFILER_D2_LIMIT");
222
223    if(ptr != NULL)
224        m_d2_limit = atol(ptr);
225
226#if 0   
227    if(m_period != 0)
228        m_log.open(insname, std::ios::out);
229#endif
230
231        SC_METHOD(transition);
232        dont_initialize();
233        sensitive << p_clk.pos();
234}
235
236tmpl()::~VciProfiler()
237{
238}
239
240tmpl(void)::transition()
241{
242    unsigned long cmd;
243    unsigned long shift;
244    unsigned long msb;
245    long x_coord;
246    long y_coord;
247    unsigned long distance;
248    unsigned long cost;
249    bool isUser;
250   
251    std::ostream &output = m_l1->m_log;
252
253    if(m_period == 0)
254        return;
255
256    if( p_vci.cmdval.read() && p_vci.cmdack.read() )
257    {
258        if(m_isPending == false)
259        {
260            m_isCMDPending = true;
261            m_isPending    = true;
262            m_tm_start     = m_tm_now;
263            cmd            = p_vci.cmd.read();
264            m_access_cntr ++;
265
266            if((cmd == vci_param::CMD_READ) && (p_vci.trdid.read() > 1))
267                cmd = VCI_iRD_CMD;
268           
269            else if((cmd == vci_param::CMD_READ) && (p_vci.pktid.read() & _CMD_ITLB))
270                cmd = VCI_iTLB_RD_CMD;
271
272            else if((cmd == vci_param::CMD_READ) && (p_vci.pktid.read() & _CMD_DTLB))
273                cmd = VCI_DTLB_RD_CMD;
274
275            else if((cmd == vci_param::CMD_LOCKED_READ) && (p_vci.pktid.read() & _CMD_ITLB))
276                cmd = VCI_iTLB_LL_CMD;
277
278            else if((cmd == vci_param::CMD_LOCKED_READ) && (p_vci.pktid.read() & _CMD_DTLB))
279                cmd = VCI_DTLB_LL_CMD;
280
281            else if((cmd == vci_param::CMD_STORE_COND) && (p_vci.pktid.read() & _CMD_ITLB))
282                cmd = VCI_iTLB_SC_CMD;
283
284            else if((cmd == vci_param::CMD_STORE_COND) && (p_vci.pktid.read() & _CMD_DTLB))
285                cmd = VCI_DTLB_SC_CMD;
286
287            m_last_cmd  = cmd;
288            m_last_addr = p_vci.address.read();
289            m_cmd_tbl[cmd].trans ++;
290            m_cmd_tbl[cmd].flits += ((p_vci.plen.read() / 4) + 1);
291
292            shift    = m_bits - m_width;
293            msb      = m_last_addr >> shift;
294            distance = 0;
295
296            m_isRemote = (msb == m_index) ? false : true;
297           
298            if(m_isRemote == true)
299            {
300                isUser   = (p_vci.pktid.read() & _CMD_USR) ? true : false;
301                m_cmd_tbl[cmd].remote ++;
302                m_remote_cntr ++;
303                x_coord  = msb >> m_yWidth;
304                y_coord  = msb & ((1 << m_yWidth) - 1);
305                distance = ABS(m_x - x_coord) + ABS(m_y - y_coord);
306               
307                output << ">> " << vci_cmd_names[cmd] 
308                       << "\t(" << m_x << "," << m_y << ") --> (" 
309                       << x_coord << "," << y_coord << ")\t[ D: " 
310                       << distance << " @: " << std::hex << m_last_addr << std::dec
311                       << " T: " << m_tm_now << " "<< ((isUser) ? "U" : "K") << " ]" << std::endl;
312               
313                m_cmd_tbl[cmd].rflits += ((p_vci.plen.read() / 4) + 1);
314                m_cmd_tbl[cmd].distance += distance;
315               
316                if(distance > m_cmd_tbl[cmd].max_dist)
317                    m_cmd_tbl[cmd].max_dist = distance;
318               
319                if(distance >= m_d2_limit)
320                    m_cmd_tbl[cmd].d2_limit ++;
321                else if(distance >= m_d1_limit)
322                    m_cmd_tbl[cmd].d1_limit ++;
323            }
324
325#if 1
326            if(m_isDebug)
327            {
328                output << ">>> " << std::dec
329                       << "Cycle: "<< m_tm_now
330                       << ", Addr " << std::hex << m_last_addr
331                       << ", isRemote " << m_isRemote
332                       << ", Distance " << distance
333                       << ", " << vci_cmd_names[m_last_cmd];
334            }
335#endif
336        }
337
338        if(p_vci.eop.read())
339            m_isPending = false;
340    }
341
342    if ( p_vci.rspval.read() && p_vci.rspack.read() )
343    {
344        if( p_vci.reop.read() )
345        {
346            m_isCMDPending = false;
347            cost = m_tm_now - m_tm_start;
348
349            m_cmd_tbl[m_last_cmd].cost += cost;
350           
351            if(m_isRemote == true)
352                m_cmd_tbl[m_last_cmd].rcost += cost;
353
354            if(cost > m_limit2)
355                m_cmd_tbl[m_last_cmd].limit2 ++;
356            else if(cost > m_limit1) 
357                m_cmd_tbl[m_last_cmd].limit1 ++;
358
359            if(m_isRemote == true)
360            {   
361                if(cost > m_cmd_tbl[m_last_cmd].rmax_cost)
362                {
363                    m_cmd_tbl[m_last_cmd].rmax_time = m_tm_now;
364                    m_cmd_tbl[m_last_cmd].rmax_cost = cost;
365                    m_cmd_tbl[m_last_cmd].raddr = m_last_addr;
366                }
367            }
368            else
369            {
370                if(cost > m_cmd_tbl[m_last_cmd].lmax_cost)
371                {
372                    m_cmd_tbl[m_last_cmd].lmax_time = m_tm_now;
373                    m_cmd_tbl[m_last_cmd].lmax_cost = cost;
374                }
375            }
376#if 1
377            if(m_isDebug)
378            {
379                output << "  <<< " << std::dec
380                       << "Cycle: "<< m_tm_now
381                       << ", Cost: " << cost
382                       << ", Addr " << std::hex << m_last_addr
383                       << ", " << vci_cmd_names[m_last_cmd]
384                       << std::endl;
385            }
386#endif
387        }
388    }
389
390    m_tm_now ++;
391    m_cycles_cntr ++;
392
393#if 1
394    if((m_isCMDPending == true) && ((m_tm_now - m_tm_start) > m_threshold) && (m_isDebug == false))
395    {
396        output << "Threshold is reached: " << std::dec
397               << "Tm_now: " << m_tm_now
398               << " Tm_start: " << m_tm_start
399               << " Val: " << m_tm_now - m_tm_start
400               << " Threshold: " << m_threshold
401               << std::endl;
402
403        m_isDebug = true;
404    }
405
406    if(m_isDebug == true)
407    {
408        m_l1->print_trace(0);
409        m_debug_cntr ++;
410    }
411
412    if(m_debug_cntr > 30)
413    {
414        m_isDebug = false;
415        print_stats();
416    }
417#endif
418
419    if((m_period != 0) && ((m_tm_now % m_period) == 0))
420    {
421        output << "Period reached, " << std::dec
422               << m_period << ", "
423               << m_tm_now << ", "
424               << m_isPeriod << ", "
425               << m_isCMDPending << std::endl;
426           
427        m_isPeriod = true;
428    }
429
430    if((m_isPeriod == true) && (m_isCMDPending == false))
431    {
432        print_stats();
433        clear_stats();
434        m_isPeriod = false;
435    }
436}
437
438}}
439
440// Local Variables:
441// tab-width: 4
442// c-basic-offset: 4
443// c-file-offsets:((innamespace . 0)(inline-open . 0))
444// indent-tabs-mode: nil
445// End:
446
447// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
448
Note: See TracBrowser for help on using the repository browser.