-
Notifications
You must be signed in to change notification settings - Fork 192
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
1 changed file
with
47 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
|
||
### Goal | ||
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. | ||
|
||
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. | ||
|
||
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. | ||
|
||
### 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. | ||
|
||
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. | ||
|
||
|
||
### 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. | ||
|
||
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. | ||
|
||
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). | ||
|
||
|
||
|
||
|