Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BLOG POST] C++ infra for bril #428

Open
wants to merge 8 commits into
base: 2023fa
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions content/blog/2023-12-11-BrilCpp.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
+++
title = "C++ Infrastructure for Bril"
[[extra.authors]]
name = "Albert Xiao"
[[extra.authors]]
name = "Ryan Mao"
[extra]
bio="""
Albert Xiao is an M.Eng student studying CS. He is particularly interested in systems and compilers development.
Ryan Mao is an M.Eng student studying CS. He is also interested in compilers.
"""
+++

## C++ Infrastructure for Bril
Albert Xiao & Ryan Mao
ryanwmao marked this conversation as resolved.
Show resolved Hide resolved

### Goal
ryanwmao marked this conversation as resolved.
Show resolved Hide resolved
Our primary aim was to enhance Bril's capabilities by incorporating a C++ interface, equipped with a parser, JSON printer, optimized types for instructions, and streamlined program flow mutations. The focus was squarely on performance, user-friendliness, and the potential to expand the Bril ecosystem with lightning-fast C++ optimizations.

### Approach
We already built a basic C++ interface for our use in the assignments and exercises throughout the course. For our final project, we used this interface as a starting point, and aimed to build off of it to create a successful framework for Bril. First and foremost, we identified critical areas of our interface for improvement: shortcomings in memory safety, performance, and user-friendliness. Our strategy was twofold: retain certain functional aspects while fundamentally revamping the framework to align with our objectives.

Our initial phase involved a meticulous redesign of Bril's program types within our framework. We restructured our infrastructure around control flow graphs (CFG), because most optimizations operate at this level. This involved functionality to divide functions into basic blocks, and equipping program types with hooks to store analysis information for later optimization. We integrated data encapsulation into our types, in order to ensure memory safety and resistance to implementation changes.
ryanwmao marked this conversation as resolved.
Show resolved Hide resolved

After the foundational framework was set in place, we iteratively tested and enhanced its usability for implementing optimizations. We implemented a few trivial optimizations in order to evaluate the usability of our framework for implementing optimizations. By iteratively developing in this fashion, we were able to identify design issues and refine the final interface.
ryanwmao marked this conversation as resolved.
Show resolved Hide resolved

As a final touch to our framework, we also enhanced its performance and memory safety. This includes incorporating string pooling, representing strings with unique integers, and numbering basic blocks and variables with serial IDs. These optimizations enable us to use more efficient data structures like integer bitsets and arrays instead of the comparatively costly hashsets and hashmaps.
ryanwmao marked this conversation as resolved.
Show resolved Hide resolved

### Challenges
The most demanding phase was establishing our foundational framework and planning for our improvements for the project. It required substantial time investment, especially in addressing all of the smaller issues and niche details. We frequently found that there were details that our initial plans did not cover, and we had to redesign our approach several times throughout the implementation process to accommodate for these issues.
ryanwmao marked this conversation as resolved.
Show resolved Hide resolved

Another critical challenge was striking a balance between the usability of our infrastructure and its optimization potential. The iterative process of testing and enhancing usability for implementing optimizations was very challenging, particularly because it was hard to view our framework from different perspectives to try and accommodate for different needs. Some of the implementation choices of our infrastructure were seemingly at odds with both of these goals; some design choices would be easier and more seamless to integrate with the functionality behind the scenes, but would be more difficult to interface with as a user, and vice versa.
ryanwmao marked this conversation as resolved.
Show resolved Hide resolved


### Evaluation

Like the Rust library, we intended to implement the brili command as seamless replacements for the current implementations. Success was measured by ensuring these commands pass checks with valgrind and demonstrate comparable runtime performance to existing implementations. Ideally, we aimed to optimize these two programs within our framework to outperform all existing implementations.
ryanwmao marked this conversation as resolved.
Show resolved Hide resolved

For overall usability, we implemented part of partial redundancy elimination. We found that the optimization itself was too complicated, but we felt that our infrastructure was pretty decent to use. We didn’t really have a better way to evaluate this metric.

We found a few memory leaks with our final iteration but our program should still be memory safe.
ryanwmao marked this conversation as resolved.
Show resolved Hide resolved

For runtime performance, we ran the existing `brili` interpreter as well as our own interpreter against the core benchmarks in the course repo. We timed the wall clock runtime of both our interpreter and the existing interpreter over all benchmarks in the folder. We observe that we can obtain upwards of 10x improvement over the previous benchmark in wall clock runtime for some of the benchmarks. ![data](https://docs.google.com/spreadsheets/d/1QoUncdD2We8P7KumqAfWIKOdVGDnGZ_klbH5AieZHrQ/edit?usp=sharing).
ryanwmao marked this conversation as resolved.
Show resolved Hide resolved
ryanwmao marked this conversation as resolved.
Show resolved Hide resolved
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's too bad that you didn't get a chance to compare against the existing fast interpreter, written in Rust. That would have been a more instructive comparison; comparing against an implementation sitting on top of a JIT mostly just measures startup time.

ryanwmao marked this conversation as resolved.
Show resolved Hide resolved