dram_lat_mem_rd_plot.py revision 13540
14484Sbinkertn@umich.edu#!/usr/bin/env python2.7
24484Sbinkertn@umich.edu
34484Sbinkertn@umich.edu# Copyright (c) 2015 ARM Limited
44484Sbinkertn@umich.edu# All rights reserved
54484Sbinkertn@umich.edu#
64484Sbinkertn@umich.edu# The license below extends only to copyright in the software and shall
74484Sbinkertn@umich.edu# not be construed as granting a license to any other intellectual
84484Sbinkertn@umich.edu# property including but not limited to intellectual property relating
94484Sbinkertn@umich.edu# to a hardware implementation of the functionality of the software
104484Sbinkertn@umich.edu# licensed hereunder.  You may use the software subject to the license
114484Sbinkertn@umich.edu# terms below provided that you ensure that this notice is replicated
124484Sbinkertn@umich.edu# unmodified and in its entirety in all distributions of the software,
134484Sbinkertn@umich.edu# modified or unmodified, in source code or in binary form.
144484Sbinkertn@umich.edu#
154484Sbinkertn@umich.edu# Redistribution and use in source and binary forms, with or without
164484Sbinkertn@umich.edu# modification, are permitted provided that the following conditions are
174484Sbinkertn@umich.edu# met: redistributions of source code must retain the above copyright
184484Sbinkertn@umich.edu# notice, this list of conditions and the following disclaimer;
194484Sbinkertn@umich.edu# redistributions in binary form must reproduce the above copyright
204484Sbinkertn@umich.edu# notice, this list of conditions and the following disclaimer in the
214484Sbinkertn@umich.edu# documentation and/or other materials provided with the distribution;
224484Sbinkertn@umich.edu# neither the name of the copyright holders nor the names of its
234484Sbinkertn@umich.edu# contributors may be used to endorse or promote products derived from
244484Sbinkertn@umich.edu# this software without specific prior written permission.
254484Sbinkertn@umich.edu#
264484Sbinkertn@umich.edu# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
274484Sbinkertn@umich.edu# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
284484Sbinkertn@umich.edu# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
294484Sbinkertn@umich.edu# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
304484Sbinkertn@umich.edu# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
314494Ssaidi@eecs.umich.edu# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
324484Sbinkertn@umich.edu# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
336121Snate@binkert.org# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
344484Sbinkertn@umich.edu# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
354484Sbinkertn@umich.edu# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
364484Sbinkertn@umich.edu# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
374484Sbinkertn@umich.edu#
384781Snate@binkert.org# Authors: Andreas Hansson
394484Sbinkertn@umich.edu
404484Sbinkertn@umich.edutry:
414484Sbinkertn@umich.edu    import matplotlib.pyplot as plt
424484Sbinkertn@umich.edu    import matplotlib as mpl
434484Sbinkertn@umich.edu    import numpy as np
444484Sbinkertn@umich.eduexcept ImportError:
454484Sbinkertn@umich.edu    print "Failed to import matplotlib and numpy"
464484Sbinkertn@umich.edu    exit(-1)
474484Sbinkertn@umich.edu
484484Sbinkertn@umich.eduimport sys
494484Sbinkertn@umich.eduimport re
504484Sbinkertn@umich.edu
514484Sbinkertn@umich.edu# This script is intended to post process and plot the output from
524484Sbinkertn@umich.edu# running configs/dram/lat_mem_rd.py, as such it parses the simout and
534484Sbinkertn@umich.edu# stats.txt to get the relevant data points.
544484Sbinkertn@umich.edudef main():
554484Sbinkertn@umich.edu
564484Sbinkertn@umich.edu    if len(sys.argv) != 2:
574484Sbinkertn@umich.edu        print "Usage: ", sys.argv[0], "<simout directory>"
584484Sbinkertn@umich.edu        exit(-1)
594484Sbinkertn@umich.edu
604484Sbinkertn@umich.edu    try:
614484Sbinkertn@umich.edu        stats = open(sys.argv[1] + '/stats.txt', 'r')
624484Sbinkertn@umich.edu    except IOError:
634484Sbinkertn@umich.edu        print "Failed to open ", sys.argv[1] + '/stats.txt', " for reading"
644484Sbinkertn@umich.edu        exit(-1)
654484Sbinkertn@umich.edu
664484Sbinkertn@umich.edu    try:
674484Sbinkertn@umich.edu        simout = open(sys.argv[1] + '/simout', 'r')
684484Sbinkertn@umich.edu    except IOError:
694484Sbinkertn@umich.edu        print "Failed to open ", sys.argv[1] + '/simout', " for reading"
704484Sbinkertn@umich.edu        exit(-1)
714484Sbinkertn@umich.edu
724484Sbinkertn@umich.edu    # Get the address ranges
734484Sbinkertn@umich.edu    got_ranges = False
744484Sbinkertn@umich.edu    ranges = []
754484Sbinkertn@umich.edu
764484Sbinkertn@umich.edu    iterations = 1
774484Sbinkertn@umich.edu
784484Sbinkertn@umich.edu    for line in simout:
794484Sbinkertn@umich.edu        if got_ranges:
804484Sbinkertn@umich.edu            ranges.append(int(line) / 1024)
814484Sbinkertn@umich.edu
824484Sbinkertn@umich.edu        match = re.match("lat_mem_rd with (\d+) iterations, ranges:.*", line)
834484Sbinkertn@umich.edu        if match:
844484Sbinkertn@umich.edu            got_ranges = True
854484Sbinkertn@umich.edu            iterations = int(match.groups(0)[0])
864484Sbinkertn@umich.edu
874484Sbinkertn@umich.edu    simout.close()
884484Sbinkertn@umich.edu
894484Sbinkertn@umich.edu    if not got_ranges:
906121Snate@binkert.org        print "Failed to get address ranges, ensure simout is up-to-date"
916121Snate@binkert.org        exit(-1)
926121Snate@binkert.org
935765Snate@binkert.org    # Now parse the stats
945765Snate@binkert.org    raw_rd_lat = []
955765Snate@binkert.org
965397Ssaidi@eecs.umich.edu    for line in stats:
975274Ssaidi@eecs.umich.edu        match = re.match(".*readLatencyHist::mean\s+(.+)\s+#.*", line)
984494Ssaidi@eecs.umich.edu        if match:
994504Ssaidi@eecs.umich.edu            raw_rd_lat.append(float(match.groups(0)[0]) / 1000)
1004494Ssaidi@eecs.umich.edu    stats.close()
1014494Ssaidi@eecs.umich.edu
1024496Ssaidi@eecs.umich.edu    # The stats also contain the warming, so filter the latency stats
1034504Ssaidi@eecs.umich.edu    i = 0
1044504Ssaidi@eecs.umich.edu    filtered_rd_lat = []
1054500Sbinkertn@umich.edu    for l in raw_rd_lat:
1064500Sbinkertn@umich.edu        if i % (iterations + 1) == 0:
1074496Ssaidi@eecs.umich.edu            pass
1084496Ssaidi@eecs.umich.edu        else:
1094487Sstever@eecs.umich.edu            filtered_rd_lat.append(l)
1104487Sstever@eecs.umich.edu        i = i + 1
1114484Sbinkertn@umich.edu
1124484Sbinkertn@umich.edu    # Next we need to take care of the iterations
1134484Sbinkertn@umich.edu    rd_lat = []
1144484Sbinkertn@umich.edu    for i in range(iterations):
1154484Sbinkertn@umich.edu        rd_lat.append(filtered_rd_lat[i::iterations])
1164484Sbinkertn@umich.edu
1175601Snate@binkert.org    final_rd_lat = map(lambda p: min(p), zip(*rd_lat))
1185601Snate@binkert.org
1195601Snate@binkert.org    # Sanity check
1205601Snate@binkert.org    if not (len(ranges) == len(final_rd_lat)):
1214484Sbinkertn@umich.edu        print "Address ranges (%d) and read latency (%d) do not match" % \
1226121Snate@binkert.org            (len(ranges), len(final_rd_lat))
1236121Snate@binkert.org        exit(-1)
1246121Snate@binkert.org
1254494Ssaidi@eecs.umich.edu    for (r, l) in zip(ranges, final_rd_lat):
126        print r, round(l, 2)
127
128    # lazy version to check if an integer is a power of two
129    def is_pow2(num):
130        return num != 0 and ((num & (num - 1)) == 0)
131
132    plt.semilogx(ranges, final_rd_lat)
133
134    # create human readable labels
135    xticks_locations = [r for r in ranges if is_pow2(r)]
136    xticks_labels = []
137    for x in xticks_locations:
138        if x < 1024:
139            xticks_labels.append('%d kB' % x)
140        else:
141            xticks_labels.append('%d MB' % (x / 1024))
142    plt.xticks(xticks_locations, xticks_labels, rotation=-45)
143
144    plt.minorticks_off()
145    plt.xlim((xticks_locations[0], xticks_locations[-1]))
146    plt.ylabel("Latency (ns)")
147    plt.grid(True)
148    plt.show()
149
150if __name__ == "__main__":
151    main()
152