コード例 #1
0
def plot(data=None, output=None):
  WORKDIR = os.getcwd()
  RESULTSDIR = data
  RESULTEXT = '.csv'
  GROUP_BAR_WIDTH = .8
  MEAN_KEY = 'mean'
  MEDIAN_KEY = 'median'
  AMAX_KEY = 'amax'
  AMIN_KEY = 'amin'
  BASE_ALLOC = 'mimalloc'

  files = []
  apps = []
  base_stats = {}
  other_stats = {}
  speedup_max = 0 # maximum observed rx mpps
  bar_colors = {
    'mimalloc': '#ddcae3',
    'tinyalloc': '#ededed',
    'tlsf': '#618c84',
    'buddy': '#49687c'
  }

  labels = {
    'mimalloc': 'mimalloc',
    'tinyalloc': 'tinyalloc',
    'tlsf': 'TLSF',
    'buddy': 'Binary Buddy'
  }

  for f in os.listdir(RESULTSDIR):
    if f.endswith(RESULTEXT):
      index = f.replace(RESULTEXT,'')
      files.append(f)

      alloc = index

      with open(os.path.join(RESULTSDIR, f), 'r') as csvfile:
        csvdata = csv.reader(csvfile, delimiter="\t")
        
        next(csvdata) # skip header

        speedups = {}

        for row in csvdata:
          if int(row[0]) not in speedups:
            speedups[int(row[0])] = []

          speedups[int(row[0])].append(float(row[1]))

          if float(row[1]) > speedup_max:
            speedup_max = float(row[1])      

        for num_queries in speedups.keys():
          if alloc == BASE_ALLOC and num_queries not in base_stats:
              base_stats[num_queries] = {
                MEAN_KEY: 0,
                MEDIAN_KEY: 0,
                AMAX_KEY: 0,
                AMIN_KEY: 0,
              }

          else:
            if num_queries not in other_stats:
              other_stats[num_queries] = {
                alloc: {
                  MEAN_KEY: 0,
                  MEDIAN_KEY: 0,
                  AMAX_KEY: 0,
                  AMIN_KEY: 0,
                }
              }

          speedup_num_queries = np.array(speedups[num_queries])

          mean = float(np.average(speedup_num_queries))
          median = float(np.median(speedup_num_queries))
          amax = float(np.amax(speedup_num_queries))
          amin = float(np.amin(speedup_num_queries))

          save_stats = {
            MEAN_KEY: mean,
            MEDIAN_KEY: median,
            AMAX_KEY: amax,
            AMIN_KEY: amin,
          }

          if alloc == BASE_ALLOC:
            base_stats[num_queries] = save_stats

          else:
            other_stats[num_queries][alloc] = save_stats

  # Calculate the relativity
  relative_stats = {}
  for num_queries in other_stats.keys():
    allocators = other_stats[num_queries]

    if num_queries not in relative_stats:
      relative_stats[num_queries] = {}

    for allocator in allocators:

      other_val = other_stats[num_queries][allocator][MEAN_KEY]
      base_val = base_stats[num_queries][MEAN_KEY]

      relative_stats[num_queries][allocator] = ((base_val - other_val)/float(other_val))*100

  # General style
  common_style(plt)

  # speedup_max += KBYTES * KBYTES * 4 # add "margin" above tallest bar

  # Setup matplotlib axis
  fig = plt.figure(figsize=(8, 5))
  renderer = fig.canvas.get_renderer()

  # image size axis
  ax1 = fig.add_subplot(1,1,1)
  ax1.set_ylabel("Relative Execution Speedup")
  # ax1.set_xlabel("Number of SQL INSERT Queries")

  ax1.grid(which='major', axis='y', linestyle=':', alpha=0.5, zorder=0)

  ax1_yticks = np.arange(-100, 50, step=20)
  print(ax1_yticks)
  ax1.set_yticks(ax1_yticks, minor=False)
  ax1.set_yticklabels([str(ytick) for ytick in ax1_yticks])

  # ax1_yticks = np.arange(0, speedup_max, step=1000000000)
  # ax1.set_yticks(ax1_yticks, minor=False)
  # ax1.set_yticklabels(ax1_yticks)
  ax1.set_ylim(-100, 50)

  # Plot coordinates
  scale = 1. / len(relative_stats.keys())
  xlabels = []

  # Adjust margining
  # fig.subplots_adjust(bottom=.15) #, top=1)



  # x = range(7)
  # negative_data = [-1,-4,-3,-2,-6,-2,-8]
  # positive_data = [4,2,3,1,4,6,7,]

  # fig = plt.figure()
  # ax = plt.subplot(111)
  # ax.bar(x, negative_data, width=1, color='r')
  # ax.bar(x, positive_data, width=1, color='b')



  i = 0
  line_offset = 0
  for numqueries in relative_stats.keys():

    # Plot a line beteween numqueries
    if i > 0:
      line = plt.Line2D([i * scale, i * scale], [-.02, 1],
          transform=ax1.transAxes, color='black',
          linewidth=1)
      line.set_clip_on(False)
      ax1.add_line(line)


    xlabels.append(numqueries)
    allocators = relative_stats[numqueries]

    # Plot a line beteween unikernel applications
    # if i > 0:
    #   line = plt.Line2D([i * scale, i * scale], [-.02, 1],
    #       transform=ax1.transAxes, color='black',
    #       linewidth=1)
    #   line.set_clip_on(False)
    #   ax1.add_line(line)

    j = 0
    bar_width = GROUP_BAR_WIDTH / len(allocators.keys())
    bar_offset = (bar_width / 2) - (GROUP_BAR_WIDTH / 2)

    # Plot each allocator
    for allocator_label in sorted(allocators):
      # app = stats[unikernel]


      relativity = relative_stats[numqueries][allocator_label]
      print(numqueries, allocator_label, relativity)

      bar = ax1.bar([i + 1 + bar_offset], relativity,
        label=labels[allocator_label],
        align='center',
        zorder=3,
        width=bar_width,
        color=bar_colors[allocator_label],
        linewidth=.5
      )
      
      ax1.text(i + 1 + bar_offset, relativity, ("%3.1f" % relativity),
        ha='center',
        va= 'bottom' if relativity > 0 else 'top',
        fontsize=LARGE_SIZE,
        linespacing=0,
        bbox=dict(pad=-.6, facecolor='white', linewidth=0),
        rotation='vertical'
      )

      bar_offset += bar_width
      j += 1

    i += 1

  # set up x-axis labels
  xticks = range(1, len(xlabels) + 1)
  ax1.set_xticks(xticks)
  # ax1.set_xticklabels(xlabels, fontsize=LARGE_SIZE, rotation=45, ha='right', rotation_mode='anchor')
  ax1.set_xticklabels(xlabels, fontsize=LARGE_SIZE, fontweight='bold')
  ax1.set_xlim(.5, len(xlabels) + .5)
  ax1.yaxis.grid(True, zorder=0, linestyle=':')
  ax1.tick_params(axis='both', which='both', length=0)

  # Create a unique legend
  handles, labels = plt.gca().get_legend_handles_labels()
  by_label = dict(zip(labels, handles))
  leg = plt.legend(by_label.values(), by_label.keys(),
    loc='lower left',
    ncol=1,
    fontsize=LARGE_SIZE,
  )
  leg.get_frame().set_linewidth(0.0)

  plt.setp(ax1.lines, linewidth=.5)

  # Save to file
  fig.tight_layout()
  fig.savefig(output) #, bbox_extra_artists=(ax1,), bbox_inches='tight')
コード例 #2
0
ファイル: plot.py プロジェクト: IMCG/eurosys21-artifacts
def plot(data=None, output=None):
  WORKDIR = os.getcwd()
  RESULTSDIR = data
  RESULTEXT = '.csv'
  IMAGESTAT = 'imagestats'
  IMAGE_SIZE_KEY = 'image_size'
  NUMSYMS_KEY = 'number_symbols'
  GROUP_BAR_WIDTH = .8
  DEFAULT = '_'

  files = []
  apps = []
  stats = {}
  throughput_max = 0 # maximum observed rx mpps
  bar_colors = {
    'linux-dpdk-vhost-user': '******',
    'linux-dpdk-vhost-net': '#000000',
    'unikraft-vhost-user': '******',
    'unikraft-vhost-net': '#8000CA'
  }
  markers = {
    'linux-dpdk-vhost-user': '******',
    'linux-dpdk-vhost-net': ',',
    'unikraft-vhost-user': '******',
    'unikraft-vhost-net': '4'
  }

  labels = {
    'linux-dpdk-vhost-user': '******',
    'linux-dpdk-vhost-net': 'Linux DPDK with vhost-net',
    'unikraft-vhost-user': '******',
    'unikraft-vhost-net': 'Rhea with vhost-net'
  }

  for f in os.listdir(RESULTSDIR):
    if f.endswith(RESULTEXT):
      index = f.replace(RESULTEXT,'')
      files.append(f)

      unikernel = index

      with open(os.path.join(RESULTSDIR, f), 'r') as csvfile:
        csvdata = csv.reader(csvfile, delimiter="\t")
        
        next(csvdata) # skip header

        for row in csvdata:
          if unikernel not in stats:
            stats[unikernel] = {}
          
          throughput = float(row[1]) * KBYTES * KBYTES
          stats[unikernel][str(row[0])] = throughput

          if throughput > throughput_max:
            throughput_max = throughput

  # General style
  common_style(plt)

  throughput_max += KBYTES * KBYTES * 1 # add "margin" above tallest bar

  # Setup matplotlib axis
  fig = plt.figure(figsize=(8, 4))
  renderer = fig.canvas.get_renderer()

  # image size axis
  ax1 = fig.add_subplot(1,1,1)
  ax1.set_ylabel("Throughout (Mp/s)")
  ax1.set_xlabel("Packet Size (Bytes)")
  ax1.grid(which='major', axis='y', linestyle=':', alpha=0.5, zorder=0)
  ax1_yticks = np.arange(0, throughput_max, step=KBYTES * KBYTES * 2)
  ax1.set_yticks(ax1_yticks, minor=False)
  ax1.set_yticklabels([sizeof_fmt(ytick, suffix='') for ytick in ax1_yticks])
  ax1.set_ylim(0, throughput_max)

  # Plot coordinates
  xlabels = list(stats[list(stats.keys())[0]].keys())

  # Adjust margining
  fig.subplots_adjust(bottom=.15) #, top=1)

  for unikernel in stats.keys():
    ax1.plot(list(stats[unikernel].keys()), list(stats[unikernel].values()),
      marker=markers[unikernel],
      label=labels[unikernel],
      zorder=3,
      linewidth=3,
      markersize=9,
      markeredgewidth=4,
      color=bar_colors[unikernel],
    )

  # set up x-axis labels
  xticks = range(0, len(xlabels))
  ax1.set_xticks(xticks)

  ax1.margins(x=.05)

  # Create a unique legend
  handles, labels = plt.gca().get_legend_handles_labels()
  by_label = dict(zip(labels, handles))
  leg = plt.legend(by_label.values(), by_label.keys(), fontsize=LARGE_SIZE, loc='upper right', ncol=1)
  leg.get_frame().set_linewidth(0.0)

  # Save to file
  fig.tight_layout()
  fig.savefig(output) #, bbox_extra_artists=(ax1,), bbox_inches='tight')
コード例 #3
0
ファイル: plot.py プロジェクト: IMCG/eurosys21-artifacts
def plot(data=None, output=None):
    WORKDIR = os.getcwd()
    RESULTSDIR = data
    RESULTEXT = '.csv'

    MINUTES = 60
    MEAN_KEY = 'mean'
    MEDIAN_KEY = 'median'
    AMAX_KEY = 'amax'
    AMIN_KEY = 'amin'
    BAR_WIDTH = 0.6

    files = []
    labels = []
    apps = []
    boottimes = {}
    boottime_max = 0  # maximum observed build time
    stack_max = 1  # number of bars to be stacked
    total_vmms = 0
    component_colors = {
        "vmm": '#9774a7',  # dark purple
        "guest": '#fff3cd',  # yellow
    }
    component_labels = {
        'vmm': 'VMM',
        "guest": 'Unikraft Guest',
    }

    colors = [
        # 'black',
        # 'dimgray',
        # 'lightcoral',
        # 'orangered',
        # 'sandybrown',
        # 'darkorange',
        # 'gold',
        # 'darkkhaki',
        # 'yellowgreen',
        # 'seagreen',
        # 'turquoise',
        # 'teal',
        # 'deepskyblue',
        # 'royalblue',
        # 'mediumpurple',
        # 'orchid',
        # 'lightskyblue',
        '#91c6e7',  # blue
        '#d18282',  # red
        '#ddcae3',  # lavender
        '#a2d9d1',  # thyme
        '#ededed',  # gray
        '#fff3cd',  # yellow
        '#91c6e7',  # light blue
        '#618c84',  # dark green
        '#49687c',  # dark blue 
        '#7c4f4f',  # dark yellow
    ]

    text_xlabels = {
        'qemu': 'QEMU',
        'qemu1nic': "QEMU (1NIC)",
        'qemumicrovm': 'QEMU\n(MicroVM)',
        'solo5': 'Solo5',
        'firecracker': 'Firecracker',
    }

    for f in os.listdir(RESULTSDIR):
        if f.endswith(RESULTEXT):
            unikernel = f.replace(RESULTEXT, '')
            files.append(f)

            if unikernel not in boottimes:
                total_vmms += 1
                boottimes[unikernel] = {
                    "guest": {
                        MEAN_KEY: 0,
                        MEDIAN_KEY: 0,
                        AMAX_KEY: 0,
                        AMIN_KEY: 0
                    }
                }

            with open(os.path.join(RESULTSDIR, f), 'r') as csvfile:
                csvdata = csv.reader(csvfile, delimiter="\t")

                next(csvdata)  # skip header

                vmm_times = []
                guest_times = []

                for row in csvdata:
                    vmm_times.append(float(row[0]) / 1000.0)
                    guest_times.append(float(row[1]) / 1000.0)

                if len(vmm_times) == 0 or len(vmm_times) != len(guest_times):
                    print("Could not parse empty data set: %s" % f)
                    continue

                guest_times = np.array(guest_times)
                vmm_times = np.array(vmm_times)

                mean_vmm = float(np.average(vmm_times))
                median_vmm = float(np.median(vmm_times))
                amax_vmm = float(np.amax(vmm_times))
                amin_vmm = float(np.amin(vmm_times))

                mean_guest = float(np.average(guest_times))
                median_guest = float(np.median(guest_times))
                amax_guest = float(np.amax(guest_times))
                amin_guest = float(np.amin(guest_times))

                if amax_guest + amax_vmm > boottime_max:
                    boottime_max = amax_guest + amax_vmm

                boottimes[unikernel]["guest"] = {
                    MEAN_KEY: mean_guest,
                    MEDIAN_KEY: median_guest,
                    AMAX_KEY: amax_guest,
                    AMIN_KEY: amin_guest,
                }
                boottimes[unikernel]["vmm"] = {
                    MEAN_KEY: mean_vmm,
                    MEDIAN_KEY: median_vmm,
                    AMAX_KEY: amax_vmm,
                    AMIN_KEY: amin_vmm,
                }

                if len(boottimes[unikernel]) > stack_max:
                    stack_max = len(boottimes[unikernel])

    # General style
    common_style(plt)

    boottime_max += 700  # margin above biggest bar

    # Setup matplotlib
    fig = plt.figure(figsize=(8, 5))
    ax = fig.add_subplot(1, 1, 1)
    ax.grid(which='major', axis='y', linestyle=':', alpha=0.5)

    # This plot:
    # ax.set_title('Unikernel Build Times', pad=35)
    ax.set_ylabel("Total Boot Time (ms)")
    # ax.set_xlabel('Applications', labelpad=10)

    # Add padding above tallest bar

    plt.ylim(0, boottime_max)

    renderer = fig.canvas.get_renderer()

    ax.set_yscale('symlog')
    # ax.set_yticks(np.arange(0, (boottime_max / MINUTES) + 10, step=2), minor=False)

    # Adjust margining
    fig.subplots_adjust(bottom=.1)  #, top=1)

    # Plot coordinates
    yticks = 0
    scale = 1. / len(text_xlabels)
    xlabels = []

    # Create a blank matrix where we'll align bar sizes for matplotlib
    means = np.zeros((stack_max, total_vmms), dict)
    labels = np.zeros((stack_max, total_vmms), dict)

    i = 0
    for vmm in text_xlabels.keys():
        # Write unikernel project on top as "header"
        lxpos = (i + .5 * len(boottimes[vmm].keys())) * scale
        xlabels.append(text_xlabels[vmm])

        # ax.text(lxpos, 1.04, r'\textbf{%s}' % unikernel, ha='center', transform=ax.transAxes, fontweight='bold')

        # # Plot a line beteween unikernel applications
        # if i > 0:
        #   line = plt.Line2D([i * scale, i * scale], [0, 1.02],
        #       transform=ax.transAxes, color='black',
        #       linewidth=1)
        #   line.set_clip_on(False)
        #   ax.add_line(line)

        components = list(boottimes[vmm].items())
        total_time = 0.

        # Plot each vmm's as a multi-bar
        j = 0
        for component_label in sorted(boottimes[vmm]):
            component = boottimes[vmm][component_label]

            means[j][i] = (component[MEAN_KEY])
            total_time += component[MEAN_KEY]
            bottom_offset = 0

            # Increase y-axis distance for the component's bar
            for k in range(j, 0, -1):
                bottom_offset += means[k - 1][i]

            # Save the component label
            labels[j][i] = (component_label)

            # Plot the bar at the correct matrix location
            bar = ax.bar([i + 1],
                         component[MEAN_KEY],
                         bottom=bottom_offset,
                         label=component_labels[component_label],
                         align='center',
                         zorder=3,
                         width=BAR_WIDTH,
                         color=component_colors[component_label],
                         linewidth=.5)

            # Write total time label if last bar
            if j == len(components) - 1:
                bottom_offset += component[MEAN_KEY]  # + .28 # + spacing

                print_total_time = "%-.01fms" % (total_time)
                #if total_time < 1:
                #  print_total_time = "%-.0fms" % (total_time * 1000)

                #elif total_time < MINUTES:
                #  print_total_time = "%-.2fs" % (total_time)

                #elif total_time > MINUTES * MINUTES:
                #  print_total_time = strftime("%-Hh %-Mm", gmtime(total_time))

                #else:
                #  print_total_time = strftime("%-Mm %-Ss", gmtime(total_time))

                plt.text(i + 1,
                         bottom_offset * 1.2,
                         print_total_time,
                         ha='center',
                         va='bottom',
                         fontsize=LARGE_SIZE,
                         linespacing=0,
                         bbox=dict(pad=-.6, facecolor='white', linewidth=0),
                         rotation='vertical')

            # add a time label for the application
            # if len(components) > 1 and component_label == DEFAULT_COMPONENET_KEY:
            #   component_seconds = component[MEAN_KEY]

            #   if component_seconds < 1:
            #     print_total_time = "%-.0fms" % (component_seconds * 1000)

            #   elif component_seconds < MINUTES:
            #     print_total_time = "%-.2fs" % (component_seconds)

            #   else:
            #     print_total_time = strftime("%-Mm%-Ss", gmtime(component_seconds))

            #   print(component_seconds, print_total_time)

            #   # Account for very  tiny applciation builds and position above axis bar
            #   yplot = bottom_offset + component[MEAN_KEY]
            #   plt.text(i + 1, yplot, r'\textbf{%s}' % print_total_time,
            #     ha='center',
            #     va='top' if round(yplot) >= 1 else 'bottom',
            #     fontsize=LARGE_SIZE,
            #     fontweight='bold',
            #     color='white',
            #     zorder=6,
            #     bbox=dict(pad=2, facecolor='none', linewidth=0),
            #     rotation='vertical'
            #   )

            j += 1

        i += 1

    xticks = range(1, total_vmms + 1)

    ax.set_xticks(xticks)
    # ax.set_xticklabels(xlabels, fontsize=LARGE_SIZE)
    ax.set_xticklabels(xlabels,
                       fontsize=LARGE_SIZE,
                       rotation=40,
                       ha='right',
                       rotation_mode='anchor')
    ax.set_xlim(.5, total_vmms + .5)
    ax.yaxis.grid(True, zorder=0, linestyle=':')
    plt.setp(ax.lines, linewidth=.5)

    # Resize plot for bottom legend
    chartBox = ax.get_position()
    # ax.set_position([chartBox.x0, chartBox.y0 + chartBox.height*0.18, chartBox.width, chartBox.height*0.82])

    # Create a unique legend
    handles, labels = plt.gca().get_legend_handles_labels()
    by_label = dict(zip(labels[::-1], handles[::-1]))
    leg = plt.legend(by_label.values(),
                     by_label.keys(),
                     loc='upper right',
                     ncol=1,
                     fontsize=LARGE_SIZE)
    leg.get_frame().set_linewidth(0.0)

    # Save to file
    fig.tight_layout()
    fig.savefig(output)
コード例 #4
0
ファイル: plot.py プロジェクト: IMCG/eurosys21-artifacts
def plot(data=None, output=None):
    RESULTSDIR = data
    RESULTEXT = '.csv'

    MINUTES = 60
    DEFAULT_COMPONENET_KEY = '_'
    MEAN_KEY = 'mean'
    MEDIAN_KEY = 'median'
    AMAX_KEY = 'amax'
    AMIN_KEY = 'amin'
    BAR_WIDTH = 0.6

    files = []
    labels = []
    apps = []
    boottimes = {}
    boottime_max = 0  # maximum observed build time
    stack_max = 1  # number of bars to be stacked
    total_allocators = 0
    component_colors = {}
    text_xlabels = {
        'buddy': 'Binary buddy',
        'mimalloc': 'Mimalloc',
        'region': 'Bootalloc',
        'tinyalloc': 'tinyalloc',
        'tlsf': 'TLSF'
    }

    colors = [
        # 'black',
        # 'dimgray',
        # 'lightcoral',
        # 'orangered',
        # 'sandybrown',
        # 'darkorange',
        # 'gold',
        # 'darkkhaki',
        # 'yellowgreen',
        # 'seagreen',
        # 'turquoise',
        # 'teal',
        # 'deepskyblue',
        # 'royalblue',
        # 'mediumpurple',
        # 'orchid',
        # 'lightskyblue',
        '#91c6e7',  # blue
        '#d18282',  # red
        '#ddcae3',  # lavender
        '#a2d9d1',  # thyme
        '#ededed',  # gray
        '#fff3cd',  # yellow
        '#91c6e7',  # light blue
        '#618c84',  # dark green
        '#49687c',  # dark blue 
        '#7c4f4f',  # dark yellow
    ]

    for f in os.listdir(RESULTSDIR):
        if f.endswith(RESULTEXT):
            allocator = f.replace(RESULTEXT, '')
            files.append(f)

            # component = None

            # if '+' in unikernel:
            #   unikernel = unikernel.split('+')
            #   component = unikernel[1]
            #   unikernel = unikernel[0]

            if allocator not in boottimes:
                total_allocators += 1
                boottimes[allocator] = {}

            with open(os.path.join(RESULTSDIR, f), 'r') as csvfile:
                csvdata = csv.reader(csvfile, delimiter="\t")

                next(csvdata)  # skip header

                execution_times = {}

                for row in csvdata:
                    if row[0] not in execution_times:
                        execution_times[row[0]] = []

                    execution_times[row[0]].append(float(row[1]) / 1000.0)

                for component in execution_times.keys():

                    # Create a unique pair for the component for an associated colour
                    if component not in component_colors.keys():
                        component_colors[component] = colors[1]
                        colors.pop(1)

                    componenet_exec_times = np.array(
                        execution_times[component])

                    mean = float(np.average(componenet_exec_times))
                    median = float(np.median(componenet_exec_times))
                    amax = float(np.amax(componenet_exec_times))
                    amin = float(np.amin(componenet_exec_times))

                    if amax > boottime_max:
                        boottime_max = amax

                    boottimes[allocator][component] = {
                        MEAN_KEY: mean,
                        MEDIAN_KEY: median,
                        AMAX_KEY: amax,
                        AMIN_KEY: amin,
                    }

                    if len(boottimes[allocator]) > stack_max:
                        stack_max = len(boottimes[allocator])

    # General style
    common_style(plt)

    boottime_max += 1.5  # margin above biggest bar

    # Setup matplotlib
    fig = plt.figure(figsize=(8, 5))
    ax = fig.add_subplot(1, 1, 1)
    ax.grid(which='major', axis='y', linestyle=':', alpha=0.5)

    # This plot:
    # ax.set_title('Unikernel Build Times', pad=35)
    ax.set_ylabel("Total Boot Time (ms)")
    # ax.set_xlabel('Applications', labelpad=10)

    # Add padding above tallest bar

    plt.ylim(0, boottime_max)

    renderer = fig.canvas.get_renderer()

    ax_yticks = np.arange(0, boottime_max, step=0.5)
    ax.set_yticklabels([str(ytick) for ytick in ax_yticks])
    ax.set_yticks(ax_yticks, minor=False)

    # ax.set_yscale('symlog')
    # ax.set_yticks(np.arange(0, (boottime_max / MINUTES) + 10, step=2), minor=False)

    # Adjust margining
    # fig.subplots_adjust(bottom=.1) #, top=1)

    # Plot coordinates
    yticks = 0
    scale = 1. / len(text_xlabels)
    xlabels = []

    # Create a blank matrix where we'll align bar sizes for matplotlib
    means = np.zeros((stack_max, total_allocators), dict)
    labels = np.zeros((stack_max, total_allocators), dict)

    i = 0
    for allocator in text_xlabels.keys():
        # Write unikernel project on top as "header"
        lxpos = (i + .5 * len(boottimes[allocator].keys())) * scale
        xlabels.append(text_xlabels[allocator])

        # ax.text(lxpos, 1.04, r'\textbf{%s}' % unikernel, ha='center', transform=ax.transAxes, fontweight='bold')

        # # Plot a line beteween unikernel applications
        # if i > 0:
        #   line = plt.Line2D([i * scale, i * scale], [0, 1.02],
        #       transform=ax.transAxes, color='black',
        #       linewidth=1)
        #   line.set_clip_on(False)
        #   ax.add_line(line)

        components = list(boottimes[allocator].items())
        total_time = 0.

        # Plot each allocator's as a multi-bar
        j = 0
        for component_label in sorted(boottimes[allocator]):
            component = boottimes[allocator][component_label]

            means[j][i] = (component[MEAN_KEY])
            total_time += component[MEAN_KEY]
            bottom_offset = 0

            # Increase y-axis distance for the component's bar
            for k in range(j, 0, -1):
                bottom_offset += means[k - 1][i]

            # Save the component label
            if component_label == DEFAULT_COMPONENET_KEY:
                component_label = DEFAULT_COMPONENET_KEY

            if component_label == DEFAULT_COMPONENET_KEY:
                labels[j][i] = (DEFAULT_COMPONENET_KEY)
            else:
                labels[j][i] = (component_label)

            # Plot the bar at the correct matrix location
            bar = ax.bar([i + 1],
                         component[MEAN_KEY],
                         bottom=bottom_offset,
                         label=component_label,
                         align='center',
                         zorder=12,
                         width=BAR_WIDTH,
                         color=component_colors[component_label],
                         linewidth=.5)

            # Write total time label if last bar
            if j == len(components) - 1:
                bottom_offset += component[MEAN_KEY]  # + .28 # + spacing
                print_total_time = round(total_time, 2)

                # if total_time < 1:

                # elif total_time < MINUTES:
                #   print_total_time = "%-.2fs" % (total_time)

                # elif total_time > MINUTES * MINUTES:
                #   print_total_time = strftime("%-Hh %-Mm", gmtime(total_time))

                # else:
                #   print_total_time = strftime("%-Mm %-Ss", gmtime(total_time))

                plt.text(i + 1,
                         bottom_offset + 0.1,
                         print_total_time,
                         ha='center',
                         va='bottom',
                         fontsize=LARGE_SIZE,
                         linespacing=0,
                         bbox=dict(pad=-.6, facecolor='white', linewidth=0),
                         rotation='vertical')

            # add a time label for the application
            # if len(components) > 1 and component_label == DEFAULT_COMPONENET_KEY:
            #   component_seconds = component[MEAN_KEY]

            #   if component_seconds < 1:
            #     print_total_time = "%-.0fms" % (component_seconds * 1000)

            #   elif component_seconds < MINUTES:
            #     print_total_time = "%-.2fs" % (component_seconds)

            #   else:
            #     print_total_time = strftime("%-Mm%-Ss", gmtime(component_seconds))

            #   print(component_seconds, print_total_time)

            #   # Account for very  tiny applciation builds and position above axis bar
            #   yplot = bottom_offset + component[MEAN_KEY]
            #   plt.text(i + 1, yplot, r'\textbf{%s}' % print_total_time,
            #     ha='center',
            #     va='top' if round(yplot) >= 1 else 'bottom',
            #     fontsize=LARGE_SIZE,
            #     fontweight='bold',
            #     color='white',
            #     zorder=6,
            #     bbox=dict(pad=2, facecolor='none', linewidth=0),
            #     rotation='vertical'
            #   )

            j += 1

        i += 1

    xticks = range(1, total_allocators + 1)

    ax.set_xticks(xticks)
    ax.set_xticklabels(xlabels, fontsize=LARGE_SIZE)
    # ax.set_xticklabels(xlabels, fontsize=LARGE_SIZE, rotation=45, ha='right', rotation_mode='anchor')
    ax.set_xlim(.5, total_allocators + .5)
    ax.yaxis.grid(True, zorder=0, linestyle=':')
    plt.setp(ax.lines, linewidth=.5)

    # Resize plot for bottom legend
    chartBox = ax.get_position()
    # ax.set_position([chartBox.x0, chartBox.y0 + chartBox.height*0.18, chartBox.width, chartBox.height*0.82])

    # Create a unique legend
    handles, labels = plt.gca().get_legend_handles_labels()
    # make sure it is in the same order as the layers
    by_label = dict(zip(labels[::-1], handles[::-1]))
    leg = plt.legend(by_label.values(),
                     by_label.keys(),
                     loc='upper right',
                     ncol=3,
                     fontsize=LARGE_SIZE,
                     columnspacing=.8)
    leg.get_frame().set_linewidth(0.0)

    # Save to file
    fig.tight_layout()
    fig.savefig(output)
コード例 #5
0
ファイル: plot.py プロジェクト: IMCG/eurosys21-artifacts
def plot(data=None, output=None):
  WORKDIR = os.getcwd()
  RESULTSDIR = data
  RESULTEXT = '.csv'
  GROUP_BAR_WIDTH = .8
  DEFAULT = '_'
  THROUGHPUT = 'throughput'
  MEAN_KEY = 'mean'
  MEDIAN_KEY = 'median'
  AMAX_KEY = 'amax'
  AMIN_KEY = 'amin'

  files = []
  labels = []
  apps = []
  stats = {}
  throughput_max = 0 # maximum observed throughput
  total_apps = 0
  bar_colors = {
    'GET': '#FFF6F9',
    'SET': '#5697C4',
  }

  labels = {
    'unikraft-qemu': 'Unikraft KVM',
    'docker': 'Docker Native',
    'hermitux-uhyve': 'Hermitux uHyve',
    'osv-qemu': 'OSv KVM',
    'rump-qemu': 'Rump KVM',
    'microvm-qemu': 'Linux KVM',
    'microvm-fc': 'Linux FC',
    'native-redis': 'Linux Native',
    'lupine-fc': 'Lupine FC',
    'lupine-qemu': 'Lupine KVM'
  }

  for f in os.listdir(RESULTSDIR):
    if f.endswith(RESULTEXT):
      unikernel = f.replace(RESULTEXT,'')

      if unikernel not in stats:
        stats[unikernel] = {}
      
      with open(os.path.join(RESULTSDIR, f), 'r') as csvfile:
        csvdata = csv.reader(csvfile, delimiter="\t")
        
        next(csvdata) # skip header

        operations = {}

        for row in csvdata:
          if row[0] not in operations:
            operations[row[0]] = []
          
          operations[row[0]].append(float(row[1])/1000.0)
        
        for operation in operations:
          all_ops = np.array(operations[operation])
          operations[operation] = {
            MEAN_KEY: np.average(all_ops),
            MEDIAN_KEY: np.median(all_ops),
            AMAX_KEY: np.amax(all_ops),
            AMIN_KEY: np.amin(all_ops)
          }

          if int(round((np.amax(all_ops)))) > throughput_max:
            throughput_max = int(round((np.amax(all_ops))))

        stats[unikernel] = operations

  # General style
  common_style(plt)

  throughput_max += 0.5 # margin above biggest bar

  # Setup matplotlib axis
  fig = plt.figure(figsize=(8, 5))
  renderer = fig.canvas.get_renderer()

  # image size axis
  ax1 = fig.add_subplot(1,1,1)
  ax1.set_ylabel("Aver. Throughput (Million req/s)")
  ax1.grid(which='major', axis='y', linestyle=':', alpha=0.5, zorder=0)
  ax1_yticks = np.arange(0, throughput_max, step=0.5)
  ax1.set_yticks(ax1_yticks, minor=False)
  ax1.set_yticklabels(ax1_yticks)
  ax1.set_ylim(0, throughput_max)

  # Plot coordinates
  scale = 1 / (len(stats.keys()))
  xlabels = []

  # Adjust margining
  # fig.subplots_adjust(bottom=.15) #, top=1)

  i = 0
  line_offset = 0
  for unikernel in [
    'hermitux-uhyve',
    'microvm-fc',
    'lupine-fc',
    'rump-qemu',
    'microvm-qemu',
    'lupine-qemu',
    'docker',
    'osv-qemu',
    'native-redis',
    'unikraft-qemu']:
    xlabels.append(labels[unikernel])
    operations = stats[unikernel]

    # Plot a line beteween unikernel applications
    if i > 0:
      line = plt.Line2D([i * scale, i * scale], [-.02, 1],
          transform=ax1.transAxes, color='black',
          linewidth=1)
      line.set_clip_on(False)
      ax1.add_line(line)

    j = 0
    bar_width = GROUP_BAR_WIDTH / len(operations.keys())
    bar_offset = (bar_width / 2) - (GROUP_BAR_WIDTH / 2)

    # Plot each application
    for operation_label in sorted(operations):
      bar = ax1.bar([i + 1 + bar_offset], operations[operation_label][MEAN_KEY],
        label=operation_label,
        align='center',
        zorder=4,
        yerr=(operations[operation_label][AMAX_KEY] - operations[operation_label][AMIN_KEY]),
        error_kw=dict(lw=1, capsize=10, capthick=1),
        width=bar_width,
        color=bar_colors[operation_label],
        linewidth=.5
      )
      
      ax1.text(i + 1 + bar_offset, operations[operation_label][AMAX_KEY] + 0.2, round(operations[operation_label][MEAN_KEY], 2),
        ha='center',
        va='bottom',
        zorder=6,
        fontsize=LARGE_SIZE,
        linespacing=0,
        bbox=dict(pad=-.6, facecolor='white', linewidth=0),
        rotation='vertical'
      )

      bar_offset += bar_width
      j += 1

    i += 1

  # sys.exit(1)

  # set up x-axis labels
  xticks = range(1, len(xlabels) + 1)
  ax1.set_xticks(xticks)
  ax1.set_xticklabels(xlabels, fontsize=LARGE_SIZE, rotation=40, ha='right', rotation_mode='anchor')#,
    # horizontalalignment='center')
  # ax1.set_xticklabels(xlabels, fontsize=LARGE_SIZE)
  ax1.set_xlim(.5, len(xlabels) + .5)
  ax1.yaxis.grid(True, zorder=0, linestyle=':')
  ax1.tick_params(axis='both', which='both', length=0)

  # Create a unique legend
  handles, labels = plt.gca().get_legend_handles_labels()
  by_label = dict(zip(labels, handles))
  leg = plt.legend(by_label.values(), by_label.keys(),
    loc='upper left',
    ncol=2,
    fontsize=LARGE_SIZE,
  )
  leg.get_frame().set_linewidth(0.0)

  plt.setp(ax1.lines, linewidth=.5)

  # Save to file
  fig.tight_layout()
  #plt.show()
  fig.savefig(output) #, bbox_extra_artists=(ax1,), bbox_inches='tight')
コード例 #6
0
ファイル: plot.py プロジェクト: IMCG/eurosys21-artifacts
def plot(data=None, output=None):
  WORKDIR = os.getcwd()
  RESULTSDIR = data
  RESULTEXT = '.csv'
  IMAGESTAT = 'imagestats'
  IMAGE_SIZE_KEY = 'image_size'
  NUMSYMS_KEY = 'number_symbols'
  GROUP_BAR_WIDTH = .8
  DEFAULT = '_'

  files = []
  labels = []
  apps = []
  imagestats = {}
  imagesize_max = 0 # maximum observed image size
  number_symbols_max = 0 # maximum observed symbol count
  total_apps = 0
  bar_colors = {
    'nginx': '#0C8828',
    'redis': '#CE1216',
    'hello': 'dimgray',
    'sqlite': '#4BA3E1'
  }

  labels = {
    'hermitux': 'Hermitux',
    'linuxuser': '******',
    'lupine': 'Lupine',
    'osv': 'OSv',
    'rump': 'Rumprun',
    'unikraft': 'Unikraft',
    'mirage': 'Mirage'
  }

  # Prepare maxplotlib data by parsing the individual .csv files.  This process
  # goes through all image sizes and number of symbols and populates a dictionary
  # of unikernels and the application "image stats" based on the framework.
  for f in os.listdir(RESULTSDIR):
    if f.endswith(RESULTEXT):
      index = f.replace(RESULTEXT,'')
      files.append(f)

      result = index.split('-')

      unikernel = result[0]
      app = result[1]

      if unikernel not in imagestats:
        imagestats[unikernel] = {}
      
      if app not in imagestats[unikernel]:
        total_apps += 1
        imagestats[unikernel][app] = 0

      if app not in apps:
        apps.append(app)

      with open(os.path.join(RESULTSDIR, f), 'r') as csvfile:
        size= int(csvfile.readline())
        imagestats[unikernel][app] = size

  # General style
  common_style(plt)

  imagesize_max += KBYTES * KBYTES * 12 # add MB "margin"
  number_symbols_max += 2000

  # Setup matplotlib axis
  fig = plt.figure(figsize=(8, 5))
  renderer = fig.canvas.get_renderer()

  # image size axis
  ax1 = fig.add_subplot(1,1,1)
  ax1.set_ylabel("Image size")
  ax1.grid(which='major', axis='y', linestyle=':', alpha=0.5, zorder=0)
  ax1_yticks = np.arange(0, imagesize_max, step=KBYTES*KBYTES*2)
  ax1.set_yticks(ax1_yticks, minor=False)
  ax1.set_yticklabels([sizeof_fmt(ytick) for ytick in ax1_yticks])
  ax1.set_ylim(0, imagesize_max)

  # Plot coordinates
  scale = 1. / len(labels.keys())
  xlabels = []

  # Adjust margining
  fig.subplots_adjust(bottom=.15) #, top=1)

  i = 0
  line_offset = 0
  for unikernel in [
      'unikraft',
      'hermitux',
      'linuxuser',
      'lupine',
      'mirage',
      'osv',
      'rump'
    ]:
    xlabels.append(labels[unikernel])
    apps = imagestats[unikernel]

    # Plot a line beteween unikernel applications
    if i > 0:
      line = plt.Line2D([i * scale, i * scale], [-.02, 1],
          transform=ax1.transAxes, color='black',
          linewidth=1)
      line.set_clip_on(False)
      ax1.add_line(line)

    j = 0
    bar_width = GROUP_BAR_WIDTH / len(apps.keys())
    bar_offset = (bar_width / 2) - (GROUP_BAR_WIDTH / 2)

    # Plot each application
    for app_label in sorted(apps):
      app = imagestats[unikernel][app_label]

      print(unikernel, app_label, app)

      bar = ax1.bar([i + 1 + bar_offset], app,
        label=app_label,
        align='center',
        zorder=3,
        width=bar_width,
        color=bar_colors[app_label],
        linewidth=.5
      )
      
      ax1.text(i + 1 + bar_offset, app + 500000, sizeof_fmt(app),
        ha='center',
        va='bottom',
        fontsize=LARGE_SIZE,
        linespacing=0,
        zorder=2,
        bbox=dict(pad=0, facecolor='white', linewidth=0),
        rotation='vertical'
      )

      bar_offset += bar_width
      j += 1

    i += 1

  # sys.exit(1)

  # set up x-axis labels
  xticks = range(1, len(xlabels) + 1)
  ax1.set_xticks(xticks)
  ax1.set_xticklabels(xlabels, fontsize=LARGE_SIZE, rotation=40, ha='right', rotation_mode='anchor')
  # ax1.set_xticklabels(xlabels, fontsize=LARGE_SIZE, fontweight='bold')
  ax1.set_xlim(.5, len(xlabels) + .5)
  ax1.yaxis.grid(True, zorder=0, linestyle=':')
  ax1.tick_params(axis='both', which='both', length=0)

  # Create a unique legend
  handles, labels = plt.gca().get_legend_handles_labels()
  by_label = dict(zip(labels, handles))
  leg = plt.legend(by_label.values(), by_label.keys(),
    loc='upper left',
    ncol=2,
    fontsize=LARGE_SIZE,
  )
  leg.get_frame().set_linewidth(0.0)

  plt.setp(ax1.lines, linewidth=.5)

  # Save to file
  fig.tight_layout()
  fig.savefig(output) #, bbox_extra_artists=(ax1,), bbox_inches='tight')
コード例 #7
0
ファイル: plot.py プロジェクト: IMCG/eurosys21-artifacts
def plot(data=None, output=None):
    RESULTSDIR = data
    RESULTEXT = '.csv'
    GROUP_BAR_WIDTH = .4
    DEFAULT = '_'
    THROUGHPUT = 'throughput'
    MEAN_KEY = 'mean'
    MEDIAN_KEY = 'median'
    AMAX_KEY = 'amax'
    AMIN_KEY = 'amin'

    files = []
    labels = []
    apps = []
    stats = {}
    throughput_max = 0  # maximum observed throughput
    total_apps = 0
    bar_color = '#5697C4'

    labels = {
        'unikraft-qemu': 'Unikraft KVM',
        'docker': 'Docker Native',
        'hermitux-uhyve': 'Hermitux uHyve',
        'osv-qemu': 'OSv KVM',
        'rump-qemu': 'Rump KVM',
        'microvm-qemu': 'Linux KVM',
        'lupine-qemu': 'Lupine KVM',
        'lupine-fc': 'Lupine FC',
        'native': 'Linux Native',
        'microvm-fc': 'Linux FC',
        'mirage-solo5': 'Mirage Solo5'
    }

    for f in os.listdir(RESULTSDIR):
        if f.endswith(RESULTEXT):
            unikernel = f.replace(RESULTEXT, '')

            if unikernel not in stats:
                stats[unikernel] = {
                    MEAN_KEY: 0,
                    MEDIAN_KEY: 0,
                    AMAX_KEY: 0,
                    AMIN_KEY: 0
                }

            with open(os.path.join(RESULTSDIR, f), 'r') as csvfile:
                csvdata = csv.reader(csvfile, delimiter="\t")

                next(csvdata)  # skip header

                throughput = []

                for row in csvdata:
                    throughput.append(float(row[0]) / 1000)

                throughput = np.array(throughput)
                throughput = {
                    MEAN_KEY: np.average(throughput),
                    MEDIAN_KEY: np.median(throughput),
                    AMAX_KEY: np.amax(throughput),
                    AMIN_KEY: np.amin(throughput)
                }

                if throughput[AMAX_KEY] > throughput_max:
                    throughput_max = throughput[AMAX_KEY]

                stats[unikernel] = throughput

    # General style
    common_style(plt)

    throughput_max += 100  # margin above biggest bar

    # Setup matplotlib axis
    fig = plt.figure(figsize=(8, 5))
    renderer = fig.canvas.get_renderer()

    # image size axis
    ax1 = fig.add_subplot(1, 1, 1)
    ax1.set_ylabel("Average Throughput (x1000 req/s)")
    ax1.grid(which='major', axis='y', linestyle=':', alpha=0.5, zorder=0)
    ax1_yticks = np.arange(0, throughput_max, step=50)
    ax1.set_yticks(ax1_yticks, minor=False)
    ax1.set_yticklabels(["%3.0f" % ytick for ytick in ax1_yticks])
    ax1.set_ylim(0, throughput_max)

    # Plot coordinates
    scale = 1. / len(stats.keys())
    xlabels = []

    # Adjust margining
    # fig.subplots_adjust(bottom=.15) #, top=1)

    i = 0
    line_offset = 0
    for unikernel in [
            'mirage-solo5', 'microvm-fc', 'lupine-fc', 'microvm-qemu',
            'rump-qemu', 'docker', 'native', 'lupine-qemu', 'osv-qemu',
            'unikraft-qemu'
    ]:
        xlabels.append(labels[unikernel])
        throughput = stats[unikernel]
        yerr = throughput[AMAX_KEY] - throughput[AMIN_KEY]

        print(unikernel, throughput[MEAN_KEY], '+/-', yerr)

        # Plot each application
        bar = ax1.bar([i + 1],
                      throughput[MEAN_KEY],
                      label=unikernel,
                      align='center',
                      zorder=4,
                      yerr=yerr,
                      width=GROUP_BAR_WIDTH,
                      color=bar_color,
                      linewidth=.5)

        ax1.text(i + 1,
                 throughput[MEAN_KEY] + yerr + 15,
                 "%3.1f" % throughput[MEAN_KEY],
                 ha='center',
                 va='bottom',
                 zorder=6,
                 fontsize=LARGE_SIZE,
                 linespacing=0,
                 bbox=dict(pad=-.6, facecolor='white', linewidth=0),
                 rotation='vertical')

        i += 1

    # sys.exit(1)

    # set up x-axis labels
    xticks = range(1, len(xlabels) + 1)
    ax1.set_xticks(xticks)
    ax1.set_xticklabels(xlabels,
                        fontsize=LARGE_SIZE,
                        rotation=45,
                        ha='right',
                        rotation_mode='anchor')
    # ax1.set_xticklabels(xlabels, fontsize=LARGE_SIZE, fontweight='bold')
    ax1.set_xlim(.5, len(xlabels) + .5)
    ax1.yaxis.grid(True, zorder=0, linestyle=':')
    ax1.tick_params(axis='both', which='both', length=0)

    # Create a unique legend
    # handles, labels = plt.gca().get_legend_handles_labels()
    # by_label = dict(zip(labels, handles))
    # leg = plt.legend(by_label.values(), by_label.keys(), loc='upper left', ncol=4)
    # leg.get_frame().set_linewidth(0.0)

    plt.setp(ax1.lines, linewidth=.5)
    # Save to file
    fig.tight_layout()
    plt.show()
    fig.savefig(output)  #, bbox_extra_artists=(ax1,), bbox_inches='tight')
コード例 #8
0
def plot(data=None, output=None):
    OUTFILE = output
    RESULTEXT = '.csv'
    KBYTES = 1024.0
    IMAGESTAT = 'imagestats'
    IMAGE_SIZE_KEY = 'image_size'
    NUMSYMS_KEY = 'number_symbols'
    GROUP_BAR_WIDTH = .8
    DEFAULT = 'default'

    files = []
    labels = []
    apps = []
    imagestats = {}
    imagesize_max = 0  # maximum observed image size
    number_symbols_max = 0  # maximum observed symbol count
    total_apps = 0
    bar_colors = {}

    text_labels = {
        DEFAULT: 'Default configuration',
        'dce': '+ Dead Code Elim. (DCE)',
        'lto': '+ Link-Time Optim. (LTO)',
        'dce+lto': '+ DCE + LTO',
        'perf': '+ Performance Optimizations'
    }

    colors = sorted([
        'sandybrown',
        'teal',
        'deepskyblue',
        'lightskyblue',
        'orchid',
    ])

    def sizeof_fmt(num, suffix='B'):
        for unit in ['', 'K', 'M', 'G']:
            if abs(num) < KBYTES:
                return "%3.1f%s%s" % (num, unit, suffix)
            num /= KBYTES
        return "%.1f%s%s" % (num, 'Yi', suffix)

    with open(data, 'r') as csvfile:
        csvdata = csv.reader(csvfile, delimiter="\t")

        for row in csvdata:
            name = row[0].split('_', 1)
            app = name[0]
            app_type = name[1].replace('_', '+')

            if app not in imagestats:
                imagestats[app] = {}
                total_apps += 1

            if app_type not in bar_colors:
                bar_colors[app_type] = colors[1]
                colors.pop(1)

            imagestats[app][app_type] = int(row[1])

    # General style
    common_style(plt)

    imagesize_max = KBYTES * KBYTES * 3.1  # add MB "margin"
    number_symbols_max += 2000

    # Setup matplotlib axis
    fig = plt.figure(figsize=(8, 5))
    renderer = fig.canvas.get_renderer()

    # image size axis
    ax1 = fig.add_subplot(1, 1, 1)
    ax1.set_ylabel("Image size")
    ax1.grid(which='major', axis='y', linestyle=':', alpha=0.5)
    ax1_yticks = np.arange(0, imagesize_max, step=KBYTES * KBYTES)
    ax1.set_yticks(ax1_yticks, minor=False)
    ax1.set_yticklabels([sizeof_fmt(ytick) for ytick in ax1_yticks])
    ax1.set_ylim(0, imagesize_max)

    # Plot coordinates
    scale = 1. / total_apps
    xlabels = []

    # Adjust margining
    fig.subplots_adjust(bottom=.15)  #, top=1)

    i = 0
    # Plot each application
    for app_label in sorted(imagestats):
        app = imagestats[app_label]
        xlabels.append(app_label)

        # Plot a line beteween unikernel applications
        if i > 0:
            line = plt.Line2D([i * scale, i * scale], [-.02, 1],
                              transform=ax1.transAxes,
                              color='black',
                              linewidth=1)
            line.set_clip_on(False)
            ax1.add_line(line)

        j = 0
        bar_width = GROUP_BAR_WIDTH / len(app.keys())
        bar_offset = (bar_width / 2) - (GROUP_BAR_WIDTH / 2)

        for app_type in [DEFAULT, 'lto', 'dce', 'dce+lto']:
            bar = ax1.bar([i + 1 + bar_offset],
                          app[app_type],
                          label=text_labels[app_type],
                          align='center',
                          zorder=3,
                          width=bar_width,
                          color=bar_colors[app_type],
                          linewidth=.5)

            ax1.text(i + 1 + bar_offset,
                     app[app_type] + 50000,
                     sizeof_fmt(app[app_type]),
                     ha='center',
                     va='bottom',
                     fontsize=LARGE_SIZE,
                     linespacing=0,
                     bbox=dict(pad=-.6, facecolor='white', linewidth=0),
                     rotation='vertical')

            bar_offset += bar_width
            j += 1
        i += 1

    # set up x-axis labels
    xticks = range(1, len(xlabels) + 1)
    ax1.set_xticks(xticks)
    ax1.set_xticklabels(xlabels,
                        fontsize=LARGE_SIZE,
                        rotation=40,
                        ha='right',
                        rotation_mode='anchor')
    # ax1.set_xticklabels(xlabels, fontsize=LARGE_SIZE, fontweight='bold')
    ax1.set_xlim(.5, len(xlabels) + .5)
    ax1.yaxis.grid(True, zorder=0, linestyle=':')
    ax1.tick_params(axis='both', which='both', length=0)

    plt.setp(ax1.lines, linewidth=.5)

    # Create a unique legend
    handles, labels = plt.gca().get_legend_handles_labels()
    by_label = dict(zip(labels, handles))
    leg = plt.legend(by_label.values(),
                     by_label.keys(),
                     loc='upper left',
                     ncol=2,
                     fontsize=LARGE_SIZE * 0.8)
    leg.get_frame().set_linewidth(0.0)

    # Save to file
    fig.tight_layout()
    fig.savefig(OUTFILE)  #, bbox_extra_artists=(ax1,), bbox_inches='tight')
コード例 #9
0
    stats = {}
    max_time = 0
    for fn in glob.glob("*.dat"):
        data = np.loadtxt(fn)
        avg = np.average(data)
        std = np.std(data)
        stats[fn] = {
            'min': avg - std,
            'avg': avg,
            'max': avg + std,
        }
        if stats[fn]['max'] > max_time:
            max_time = stats[fn]['max']

    # General style
    common_style(plt)

    max_time *= 1.2  # Margin above biggest bar

    fig = plt.figure(figsize=(8, 4))
    ax = fig.add_subplot(1, 1, 1)
    ax.set_ylabel("Time (seconds)", fontsize=LARGE_SIZE)
    ax.grid(which='major', axis='y', linestyle=':', alpha=0.5, zorder=0)
    yticks = np.arange(0, max_time, step=1)
    ax.set_yticks(yticks, minor=False)
    ax.set_yticklabels(["%3.0f" % ytick for ytick in yticks])
    ax.set_ylim(0, max_time)

    xlabels = []
    i = 0
    for experiment in labels.keys():
コード例 #10
0
ファイル: plot.py プロジェクト: IMCG/eurosys21-artifacts
def plot(data=None, output=None):
    WORKDIR = os.getcwd()
    RESULTSDIR = data
    RESULTEXT = '.csv'
    GROUP_BAR_WIDTH = .8
    DEFAULT = '_'

    files = []
    labels = []
    apps = []
    memstats = {}
    memusage_max = 0  # maximum observed memory size
    total_apps = 0
    bar_colors = {
        'nginx': '#0C8828',
        'redis': '#CE1216',
        'hello': 'dimgray',
        'sqlite': '#4BA3E1'
    }

    labels = {
        'unikraft': 'Unikraft',
        'docker': 'Docker',
        'hermitux': 'Hermitux',
        'lupine': 'Lupine',
        'osv': 'OSv',
        'rump': 'Rumprun',
        'microvm': 'Linux\nMicroVM'
    }

    for f in os.listdir(RESULTSDIR):
        if f.endswith(RESULTEXT):
            index = f.replace(RESULTEXT, '')
            unikernel = index

            if unikernel not in memstats:
                memstats[unikernel] = {}

            with open(os.path.join(RESULTSDIR, f), 'r') as csvfile:
                csvdata = csv.reader(csvfile, delimiter="\t")

                next(csvdata)  # skip header

                for row in csvdata:
                    app = row[0]

                    memusagemb = int(row[1]) * KBYTES * KBYTES
                    memstats[unikernel][app] = memusagemb

                    if memusagemb > memusage_max:
                        memusage_max = memusagemb

    # General style
    common_style(plt)

    memusage_max += KBYTES * KBYTES * 14  # add MB "margin"

    # Setup matplotlib axis
    fig = plt.figure(figsize=(8, 5))
    renderer = fig.canvas.get_renderer()

    # image size axis
    ax1 = fig.add_subplot(1, 1, 1)
    ax1.set_ylabel("Minimum Memory Requirement")
    ax1.grid(which='major', axis='y', linestyle=':', alpha=0.5, zorder=0)
    ax1_yticks = np.arange(0, memusage_max, step=KBYTES * KBYTES * 8)
    ax1.set_yticks(ax1_yticks, minor=False)
    ax1.set_yticklabels([sizeof_fmt(ytick) for ytick in ax1_yticks])
    ax1.set_ylim(0, memusage_max)

    # Plot coordinates
    scale = 1. / len(memstats.keys())
    xlabels = []

    # Adjust margining
    # fig.subplots_adjust(bottom=.) #, top=1)

    i = 0
    line_offset = 0
    for unikernel in [
            'unikraft', 'docker', 'rump', 'hermitux', 'lupine', 'osv',
            'microvm'
    ]:
        xlabels.append(labels[unikernel])
        apps = memstats[unikernel]

        # Plot a line beteween unikernel applications
        if i > 0:
            line = plt.Line2D([i * scale, i * scale], [-.02, 1],
                              transform=ax1.transAxes,
                              color='black',
                              linewidth=1)
            line.set_clip_on(False)
            ax1.add_line(line)

        j = 0
        bar_width = GROUP_BAR_WIDTH / len(apps.keys())
        bar_offset = (bar_width / 2) - (GROUP_BAR_WIDTH / 2)

        # Plot each application
        for app_label in sorted(apps):
            app = memstats[unikernel][app_label]

            print(unikernel, app_label, app)

            bar = ax1.bar([i + 1 + bar_offset],
                          app,
                          label=app_label,
                          align='center',
                          zorder=3,
                          width=bar_width,
                          color=bar_colors[app_label],
                          linewidth=.5)

            ax1.text(
                i + 1.02 + bar_offset,
                app + 1000000,
                sizeof_fmt(app),
                ha='center',
                va='bottom',
                fontsize=LARGE_SIZE,
                linespacing=0,
                #bbox=dict(pad=-.6, facecolor='white', linewidth=0),
                rotation='vertical')

            bar_offset += bar_width
            j += 1

        i += 1

    # sys.exit(1)

    # set up x-axis labels
    xticks = range(1, len(xlabels) + 1)
    ax1.set_xticks(xticks)
    ax1.set_xticklabels(xlabels,
                        fontsize=LARGE_SIZE,
                        rotation=40,
                        ha='right',
                        rotation_mode='anchor')
    # ax1.set_xticklabels(xlabels, fontsize=LARGE_SIZE, fontweight='bold')
    ax1.set_xlim(.5, len(xlabels) + .5)
    ax1.yaxis.grid(True, zorder=0, linestyle=':')
    ax1.tick_params(axis='both', which='both', length=0)

    # Create a unique legend
    handles, labels = plt.gca().get_legend_handles_labels()
    by_label = dict(zip(labels, handles))
    leg = plt.legend(
        by_label.values(),
        by_label.keys(),
        loc='upper left',
        ncol=2,
        fontsize=LARGE_SIZE,
    )
    leg.get_frame().set_linewidth(0.0)

    plt.setp(ax1.lines, linewidth=.5)

    # Save to file
    fig.tight_layout()
    fig.savefig(output)  #, bbox_extra_artists=(ax1,), bbox_inches='tight')