Пример #1
0
def intro_slide(slides: Slides):
    slide = slides.new_slide()
    slide.set_style("text", s(size=60, bold=True))
    slide.set_style("orange", slide.get_style("text"), s(color="orange"))

    fast = slide.box()
    fast.text("~orange{Fast} & Safe", style="text")

    slide.box(height=100)

    line = slide.box(width="fill", horizontal=True)
    development = line.box(width="50%", y=0)
    development.overlay().text("Quick development")
    performance = line.box(width="50%", y=0)
    performance.text("High performance", style=s(color="orange"))

    arrow = Arrow(20)
    slide.box().line(
        [fast.p("15%", "100%"), development.p("50%", 0)],
        stroke_width=5,
        color="orange",
        end_arrow=arrow)
    slide.box().line(
        [fast.p("15%", "100%"), performance.p("50%", 0)],
        stroke_width=5,
        color="orange",
        end_arrow=arrow)
Пример #2
0
def adt(slides: Slides):
    slide = slides.new_slide()
    slide.update_style("code", s(size=26))
    content = slide_header(
        slide, """Algebraic data types/tagged unions/sum types/
discriminated unions/variants""")

    code_width = 960
    code(content.box(),
         """
enum Packet {
    Header { source: u32, tag: u32, data: Vec<u8> },
    Payload { data: Vec<u8> },
    Ack { seq: u64 }
}""",
         width=code_width)

    content.box(height=10)
    content.box(show="next+").text("Pattern matching",
                                   style=s(bold=True, size=40))

    code(content.box(show="last+"),
         """
match socket.get_packet() {
    Header {data, ..} | Payload {data, ..} => { },
    _ => { println!("Packet without data"); }
}
""",
         width=code_width)

    content.box(height=10)
    content.box(
        show="next+").text("The compiler forces you to handle all variants")
Пример #3
0
def design(slides: Slides):
    slide = slides.new_slide()
    content = slide_header(slide, "Design by community")

    list = content.box()
    list_item(list).text("Open source")
    list_item(list).text("RFC")
    list.box(width=700, height=200, p_top=40).image("imgs/rust-rfc.png")

    slide = slides.new_slide()
    content = slide_header(slide, "Backwards compatibility")

    small = s(size=28)

    list = content.box()
    list_item(list).text("Strong BC guarantees")
    list_item(list, show="2+").text("New version every 6 weeks")
    list_item(list, show="2+", level=1).text(
        "Thousands of libraries tested to spot regressions", style=small)
    list_item(list, show="3+").text("Big changes => new edition")
    list_item(list, show="3+", level=1).text("Rust 2015 vs Rust 2018",
                                             style=small)

    slide = slides.new_slide()
    slide.update_style("code", s(size=38))
    content = slide_header(slide, "Unstable features")

    code(content.box(), """
#![feature(async_await)]
async fn foo() {
    ...
}""")

    content.box(height=20)
    bash(content.box(show="2+"), "$ cargo +nightly build")
Пример #4
0
def intro_slide(slides: Slides):
    slide = slides.new_slide()
    slide.set_style("text", s(size=60, bold=True))
    slide.set_style("orange",
                    slide.get_style("text").compose(s(color="orange")))

    safe = slide.box()
    safe.text("Fast & ~orange{Safe}", style="text")

    slide.box(height=100)

    line = slide.box(width="fill", horizontal=True)
    development = line.box(width="50%", y=0)
    development.overlay(show="2-3").text("Memory safety")
    development.overlay(show="4").text("Memory safety",
                                       style=s(color="orange"))
    performance = line.box(width="50%", y=0, show="3+")
    performance.text("Fearless concurrency")

    arrow = Arrow(20)
    slide.box(show="2+").line(
        [safe.p("80%", "100%"), development.p("50%", 0)],
        stroke_width=5,
        color="orange",
        end_arrow=arrow)
    slide.box(show="3+").line(
        [safe.p("80%", "100%"), performance.p("50%", 0)],
        stroke_width=5,
        color="orange",
        end_arrow=arrow)
Пример #5
0
def intro(slides: SlideDeck):
    slide = new_slide(slides)
    slide.box().text(
        """CPU design effects
that can degrade performance of your programs""", s(bold=True, size=40))

    slide.box(p_top=40).text("""Jakub Beránek
[email protected]""", s(bold=False, size=30))

    slide = new_slide(slides)
    content = slide_header(slide, "~tt{whoami}")
    list_wrapper = content.box()
    list_item(list_wrapper).text(
        "PhD student @ VSB-TUO, Ostrava, Czech Republic")
    list_item(list_wrapper).text(
        "Research assistant @ IT4Innovations (HPC center)")
    list_item(list_wrapper).text(
        "HPC, distributed systems, program optimization")

    slide = new_slide(slides)
    content = slide_header(slide, "How do we get maximum performance?")
    list_wrapper = content.box()
    list_item(list_wrapper).text("Select the right algorithm")
    list_item(list_wrapper, show="next+").text("Use a low-overhead language")
    list_item(list_wrapper, show="next+").text("Compile properly")
    list_item(list_wrapper,
              show="next+").text("~bold{Tune to the underlying hardware}")
Пример #6
0
def parallelization(slides: Slides):
    slide = slides.new_slide()
    content = slide_header(slide, "Concurrency primitives")

    list = content.box()
    list_item(list).text("Mutexes")
    list_item(list, show="next+").text("Condition variables")
    list_item(list, show="next+").text("Atomics")
    list_item(list, show="next+").text("Synchronized queues")

    slide = slides.new_slide()
    slide.update_style("code", s(size=30))
    content = slide_header(slide, "Shared-memory parallelism")
    content.box().text("No OpenMP ☹")

    code_width = 800

    content.box(height=40)
    rayon = content.box(show="2+")
    rayon_box = rayon.box(horizontal=True)
    rayon_box.box().text("Rayon (+ Rayon adaptive")
    rayon_box.box(width=20)
    rayon_box.box(width=60).image("imgs/saurabh.png")
    rayon_box.box().text(" )")
    rayon.box(height=30)
    code_box = code(rayon.box(),
                    """
fn sum_of_squares(input: &[i32]) -> i32 {
    input.par_iter()
         .map(|&i| i * i)
         .sum()
}""",
                    width=code_width)
    code_box.line_box(1, z_level=99, x=165, width=165,
                      show="3+").rect(bg_color=CODE_HIGHLIGHT_COLOR)

    code(rayon.box(show="4+"),
         """
#[parallel]
for x in 0..10 {
    println!("{}", x);
}""",
         width=code_width)

    slide = slides.new_slide()
    slide.update_style("code", s(size=26))
    content = slide_header(slide, "Message-passing")
    code(
        content, """
let universe = mpi::initialize();
let world = universe.world();
let size = world.size();
let rank = world.rank();

if rank == 0 {
    let (msg, status) = world.any_process().receive_vec();
}
""")
Пример #7
0
def bash(parent: Box, code: str, text_style=None, **box_args):
    if text_style is None:
        text_style = s()

    text_style = text_style.compose(s(color="#E9E9ED", font="monospace"))

    wrapper = parent.box(**box_args)
    wrapper.rect(bg_color="#3F3F3F")
    code_wrapper = wrapper.box(x=0, p_x=10, p_y=5)
    return code_wrapper.text(code, style=text_style)
Пример #8
0
def intrinsics(slides: Slides):
    slide = slides.new_slide()
    slide.update_style("code", s(size=38))

    content = slide_header(slide, "Branch prediction")

    code(
        content.box(), """
if core::intrinsic::likely(condition) {
    ...
} else #[cold] {
    ...
}""")

    slide = slides.new_slide()
    slide.update_style("code", s(size=34))
    content = slide_header(slide, "SIMD")

    code_width = 900
    code(content.box(),
         """
#[cfg(target_arch = "x86_64")]
use std::arch::x86_64::_mm256_add_epi64;

_mm256_add_epi64(...);""",
         width=code_width)

    content.box(height=50)
    code(content.box(show="2+"),
         """
data.simd_iter()
    .simd_map(|v| {
        f32s(9.0) * v.abs().sqrt().ceil() -
        f32s(4.0) - f32s(2.0)
    })
    .scalar_collect();""",
         width=code_width)

    slide = slides.new_slide()
    slide.update_style("code", s(size=38))
    content = slide_header(slide, "Inline assembly")

    code(
        content.box(), """
fn add(a: i32, b: i32) -> i32 {
    let c: i32;
    unsafe {
        asm!("add $2, $0"
             : "=r"(c)
             : "0"(a), "r"(b));
    }
    c
}""")
Пример #9
0
def rust_safety(slides: Slides):
    slide = slides.new_slide()
    slide.set_style("text", s(size=60, bold=True))

    slide.box().text("Rust is safe...", style="text")
    slide.box(show="2+").text("...but from what?", style="text")

    slide = slides.new_slide()
    content = slide_header(slide, "Undefined behaviour")
    content.box(width=800).image("imgs/cpp-undefined.png")

    slide = slides.new_slide()
    content = slide_header(slide, "UB in Java")
    content.box().text("Java::Iterator::remove")
    with_bg(content.box()).text(
        """“The behavior of an iterator is ~emph{unspecified} if the underlying
collection is modified while the iteration is in progress in any way
other than by calling this method, unless an overriding class has specified
a concurrent modification policy.”
""",
        style=s(size=28, align="left"))

    slide = slides.new_slide()
    content = slide_header(slide, "UB in Python")
    content.box().text("~tt{for} statement")
    with_bg(content.box()).text(
        """“There is a subtlety when the sequence is being modified by the loop (this can only
occur for mutable sequences, e.g. lists). An internal counter is used to keep track
of which item ... ~emph{This can lead to nasty bugs} that can be avoided by making a
temporary copy using a slice of the whole sequence ...”
""",
        style=s(size=24, align="left"))

    slide = slides.new_slide()
    content = slide_header(slide, "Sources of UB")
    list = content.box()
    items = [
        "Null pointer dereference", "Double-free", "Use-after-free",
        "Out-of-bounds access", "Integer conversion", "Integer overflow",
        "Iterator invalidation", "Invalid alignment", "…"
    ]
    for item in items:
        list_item(list, show="next+").text(item)

    content.box(height=20)
    content.box(show="next+").text(
        "Rust tries very hard to avoid all of the above",
        style=s(size=44, bold=True))
Пример #10
0
def zero_cost(slides: Slides):
    slide = slides.new_slide()
    content = slide_header(slide, "Zero-cost abstractions")
    content.box().text("Bjarne Stroustrup:", s(size=60))

    with_bg(content.box()).text("""What you don’t use, you don’t pay for.
What you do use, you couldn’t hand code any better.""")
Пример #11
0
def structures(slides: Slides):
    slide = slides.new_slide()
    slide.update_style("code", s(size=26))
    content = slide_header(slide, "Structures")

    code_width = 920
    code(content.box(),
         """
struct Person {
    pub age: u32,
    name: String
}
""",
         width=code_width)

    code(content.box(show="next+"),
         """
impl Person {
    pub fn new(age: u32, name: String) -> Person {
        Person { age, name }
    }
    pub fn is_adult(&self) -> bool {
        self.age >= 18
    }
}    
""",
         width=code_width)
Пример #12
0
def false_sharing(slides: SlideDeck, backup: bool):
    if backup:
        slide = new_slide(slides)
        content = slide_header(slide, "Code (backup)")
        code(
            content.box(), """// tid - [0, NO_OF_THREADS)
void thread_fn(int tid, double* data)
{
    size_t repetitions = 1024 * 1024 * 1024UL;
    for (size_t i = 0; i < repetitions; i++)
    {
        data[tid] *= i;
    }
}""")
        slide = new_slide(slides)
        content = slide_header(slide, "Result (backup)")
        content.box(height=600).image("images/example3-time.png")

    slide = new_slide(slides)
    content = slide_header(slide, "Cache system")
    content.box(height=600).image("images/haswell-diagram.png")
    content.box(width=230, height=40, x=816, y=530).rect(color=COLOR_BACKEND,
                                                         stroke_width=3)
    content.box(width=226, height=40, x=240, y=570).rect(color=COLOR_BACKEND,
                                                         stroke_width=3)

    slide = new_slide(slides)
    content = slide_header(slide, "Cache coherency")
    content.box(height=600).image("images/false-sharing.svg")

    slide = new_slide(slides)
    content = slide_header(slide, "False sharing")
    content.box(width="90%").image("images/false-sharing-array.svg")

    slide = new_slide(slides)
    content = slide_header(slide, "How to measure?")
    content.box().text("~tt{l2_rqsts.all_rfo}", s(size=48))
    content.box(p_top=20).text(
        "How many times some core invalidated data in other cores?")

    if backup:
        bash(content.box(p_top=40, show="next+"),
             """$ perf stat -e l2_rqsts.all_rfo ./example3
1 thread   ->        59 711
2 threads  -> 1 112 258 710""",
             text_style=s(align="left"))
Пример #13
0
def benchmark_game(slides: Slides):
    slide = slides.new_slide()
    content = slide_header(slide, "Benchmark game")
    content.box(width=900).image("imgs/benchmark-game.png")
    content.box().text(
        "https://benchmarksgame-team.pages.debian.net/benchmarksgame/fastest/gpp"
        "-rust.html",
        style=s(size=20))
Пример #14
0
    def unsafe_slide(header, code_body, content_show="1", code_size=36):
        slide = slides.new_slide()
        slide.update_style("code", s(size=code_size))
        content = slide_header(slide, "Unsafe Rust")
        content.box(y=0).text("Unsafe Rust allows:")

        content.box(height=20)
        content.box(show=content_show).text(header)
        content.box(height=10)
        code(content.box(show=content_show), code_body)
Пример #15
0
def make_presentation(path: str, backup: bool):
    slides = new_slides(1280, 720)

    slides.update_style("default", s(font=FONT, size=36,
                                     color=COLOR1))  # Default font
    slides.update_style("emph", s(color=COLOR2))  # Emphasis
    slides.update_style("code", s(size=32))
    slides.set_style("bold", s(bold=True))
    slides.set_style("notice", s(color=COLOR_NOTE, bold=True))

    intro(slides)
    hw_complexity(slides)
    branch_prediction(slides, backup)
    cache_conflicts(slides, backup)
    denormals(slides, backup)
    outro(slides)
    finish_slides(slides)
    false_sharing(slides, backup)

    slides.render(path)
Пример #16
0
def slide_header(box: Box,
                 text: str,
                 return_header=False) -> Union[Box, Tuple[Box, Box]]:
    header = box.box(width="fill", height="10%").rect(bg_color="#23363A")
    row = header.box(horizontal=True)
    row.box().text(text, style=s(size=40, bold=True, color="#FFFFFF"))

    content = box.box(height="fill", width="fill")
    if return_header:
        return (content, row)
    return content
Пример #17
0
    def person_slide(end=""):
        slide = slides.new_slide()
        slide.update_style("code", s(size=50))
        content = slide_header(slide, "Ownership")
        return (slide,
                code(content,
                     """
fn foo(bitmap: Bitmap) {{
    ...
}}{}""".format(end),
                     width=840))
Пример #18
0
def runtime(slides: Slides):
    slide = slides.new_slide()
    slide.update_style("default", s(size=40))
    content = slide_header(slide, "Minimal runtime")

    list = content.box()
    list_item(list, show="next+").text("No GC")
    list.box(width=600, height=400, show="last+",
             padding=0).image("imgs/gc.svg")
    list_item(list, show="next+").text("No exceptions")
    list_item(list, show="next+").text("Tight data layout")
    list_item(list, show="next+").text("Supports embedded platforms")
Пример #19
0
def multiphase_compiler(slides: Slides):
    slide = slides.new_slide()
    slide.update_style("code", s(size=34))
    content = slide_header(slide, "Multi-phase compiler")

    code(
        content.box(), """
fn main() {
    look_ma_no_forward_declaration();
}

fn look_ma_no_forward_declaration() { }
""")
Пример #20
0
def message_passing(slides: Slides):
    slide = slides.new_slide()
    slide.update_style("code", s(size=38))
    content = slide_header(slide, "Message passing")

    code_width = 900
    code_step(content.box(width=code_width, height=300), """
let (tx, rx) = mpsc::channel();
thread::spawn(move || {
    tx.send(5);
});
let received = rx.recv();
""", "1", (
        ("               mpsc::channel();", None, None, None, None),
        (0, None, None, None, None),
        (0, 1, 2, 3, None),
        (0, 1, 2, 3, 4)
    ), width=code_width)

    content.box(height=20)
    content.box(show="next+").text("""Splitting a channel into a receiver + sender removes aliasing
    and allows moving the sender independently of the receiver.""", s(size=34))
Пример #21
0
    def address(cols, content, next=True, use_style=True, row=0):
        for i, col in enumerate(cols):
            show = "1+"
            if next:
                show = "next+" if i == 0 else "last+"

            style = "default"
            if use_style:
                if i == 0:
                    style = s(color=colors[row])
                else:
                    style = styles[i - 1]
            col.box(show=show).text(content[i], style=style)
Пример #22
0
def modules(slides: Slides):
    slide = slides.new_slide()
    slide.update_style("code", s(size=24))
    slide.set_style("bold", s(bold=True))
    content = slide_header(slide, "Proper module system")

    line = content.box(width="fill", horizontal=True)
    lib = line.box(width="50%", y=0)
    text_box = lib.box()
    text_box.box(show="1").text("foo.rs")
    text_box.overlay(show="next+").text("~bold{foo}.rs")
    code(
        lib.box(), """
pub fn fun1() {
    println!("fun1");
}
fn fun2() {
    println!("fun2");
}
""")

    main = line.box(width="50%", y=0, show="2+")
    main.box().text("main.rs")
    code(
        main.box(), """
use foo;

fn main() {
    foo::fun1();
    // foo::fun2(); private
}""")

    content.box(height=60)
    advantages = content.box(show="3+")
    advantages.update_style("default", s(size=40))
    list_item(advantages).text("visibility control")
    list_item(advantages).text("self-contained")
Пример #23
0
    def array(numbers, predictions, start=1, needle=6):
        stroke_width = 2
        size = 36
        for i in range(len(numbers)):
            box = row.box(width=box_dimension,
                          height=box_dimension).rect(color="black",
                                                     stroke_width=stroke_width)
            number = str(numbers[i])
            box.text(number, s(bold=True, size=size))

            predicted_correctly = (predictions[i] and numbers[i] < needle) or (
                not predictions[i] and numbers[i] >= needle)
            prediction = "green" if predicted_correctly else "red"
            show_overlay = "{}+".format(start + i * 2 + 1)
            overlay = box.overlay(show=show_overlay).rect(
                color="black", bg_color=prediction, stroke_width=stroke_width)
            overlay.text(number, s(color="white", bold=True, size=size))
            show_text = start + i * 2
            row.box(x=i * box_dimension,
                    y=box_dimension,
                    width=box_dimension,
                    show="{}-{}".format(show_text,
                                        show_text + 1)).text("{} < {}?".format(
                                            number, needle))
Пример #24
0
    def cpp_lifetime(comment=""):
        slide = slides.new_slide()
        slide.update_style("code", s(size=38))
        content = slide_header(slide, "Lifetimes (C++)")
        code(content,
             """
int* p;
{{
    int value = 5;
    p = &value;
}}{comment}
std::cout << *p << std::endl;
""".format(comment=comment),
             "cpp",
             width=800)
Пример #25
0
def caveats(slides: Slides):
    slide = slides.new_slide()
    content = slide_header(slide, "Performance caveats")

    l1_style = s(size=26)

    list = content.box()
    list_item(list).text("Out-of-bounds checks")
    list_item(list, level=1,
              show="2+").text("Can be optimized away (iterators)",
                              style=l1_style)
    list_item(list, show="3+").text("Integer overflow is not undefined")
    list_item(list, level=1,
              show="4+").text("Runtime checks only in debug mode",
                              style=l1_style)
Пример #26
0
def intro(slides: Slides):
    slide = slides.new_slide()
    slide.set_style("title", s(size=60, bold=True))
    slide.set_style("name", s(size=30))

    slide.sbox(height="30%").image("imgs/logo.svg")
    slide.box(height=80)
    slide.box().text("Rust: Fast & Safe", "title")
    slide.box(height=20)
    slide.box().text("Jakub Beránek, Mathieu Fehr, Saurabh Raje", "name")

    slide = slides.new_slide()
    slide.box(width=500).image("imgs/meme-rust-meeting.jpg")

    slide = slides.new_slide()
    content = slide_header(slide, "What is Rust?")
    content.box().text("""
System programming language for building
reliable and efficient software.""")

    content.box(height=20)
    content.box(width="fill", height=150, show="2+").image("imgs/history.svg")
    content.box(height=20)
    content.box(width="fill", height=350, show="3+").image("imgs/users.svg")
Пример #27
0
def constexpr(slides: Slides):
    slide = slides.new_slide()
    slide.update_style("code", s(size=38))

    content = slide_header(slide, "Constexpr functions")

    code(
        content.box(), """
const fn double(x: i32) -> i32 {
    x * 2
}

const FIVE: i32 = 5;
const TEN: i32 = double(FIVE);
""")
Пример #28
0
def outro(slides: SlideDeck):
    slide = new_slide(slides)
    content = slide_header(slide, "There are many other effects")
    list_wrapper = content.box()
    list_item(list_wrapper).text("NUMA")
    list_item(list_wrapper).text("4k aliasing")
    list_item(list_wrapper).text("Misaligned accesses, cache line boundaries")
    list_item(list_wrapper).text("Instruction data dependencies")
    list_item(list_wrapper).text("Software prefetching")
    list_item(list_wrapper).text("Non-temporal stores & cache pollution")
    list_item(list_wrapper).text("Bandwidth saturation")
    list_item(list_wrapper).text("DRAM refresh intervals")
    list_item(list_wrapper).text("AVX/SSE transition penalty")
    list_item(list_wrapper).text("...")

    slide = new_slide(slides)
    slide.box().text("Thank you!", s(bold=True, size=60))
    slide.box(p_top=60).text(
        """For more examples visit:
~tt{github.com/kobzol/hardware-effects}""", s(size=44))
    slide.box(p_top=80).text("Jakub Beránek")

    slide.box(p_top=100).text(
        "Slides built with ~tt{github.com/spirali/elsie}", s(size=30))
Пример #29
0
def generics(slides: Slides):
    slide = slides.new_slide()
    slide.update_style("code", s(size=30))
    content = slide_header(slide, "Generics")

    code_width = 900

    code(content.box(),
         """
struct KeyValue<K, V> {
    key: K,
    value: V
}""",
         width=code_width)
    code(content.box(show="next+"),
         """
trait Buffer<T> {
    fn read(&self) -> T;    
}""",
         width=code_width)

    content.box(height=10)
    code(content.box(show="next+"),
         """
fn print_buffer<B: Buffer<T>, T: Display>(buffer: B) {
    println!("{}", buffer.read());
}""",
         width=code_width)
    code(content.box(show="next+"),
         """
fn print_bigger<T: PartialEq + Display>(a: T, b: T) {
    if (a > b) { println!("{}", a); }
}
""",
         width=code_width)

    content.box(height=10)
    code(content.box(show="next+"),
         """
impl <T: Display> Serialize for T {
    ...
}
""",
         width=code_width)
Пример #30
0
def concurrency_issues(slides: Slides):
    slide = slides.new_slide()
    content = slide_header(slide, "Concurrency issues")

    content.box().text("Rust doesn't prevent:")
    list = content.box()
    list_item(list, show="next+").text("Deadlocks")
    list_item(list, show="next+").text("General race conditions")

    content.box(height=20)
    content.box(show="next+").text("Rust prevents (at compile time):")
    list = content.box()
    list_item(list, show="next+").text("Data races")

    slide = slides.new_slide()
    content = slide_header(slide, "What causes data races?")

    text_style = s(size=50)
    content.box(show="next+").text("Concurrent aliasing and mutability...", style=text_style)
    content.box(show="next+").text("...but Rust already disables that!", style=text_style)

    content.box(height=20)
    content.box(show="next+").text("So how do we get any concurrency at all...?", style=text_style)