save the earth, program in c++! · 2019. 5. 9. · 2019.05.10. porkoláb: save the earth, program...

108
SAVE THE EARTH, PROGRAM IN C++! Zoltán Porkoláb Ericsson / Eötvös Loránd University

Upload: others

Post on 16-Aug-2021

2 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

SAVE THE EARTH,PROGRAM IN C++!

Zoltán PorkolábEricsson / Eötvös Loránd University

Page 2: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 2

C++ applications

● C++ is used in various environments

– High performance computing

– GPGPU programming

– Large system implementation (like telecom)

– Device drivers (e.g. Arduino)

– Low energy environments (e.g. Mars rover)

– Performance critical systems (e.g. F35)

Page 3: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 3

Related work

Rui Pereira, Marco Couto, Francisco Ribeiro, Rui Rua, Jácome Cunha, João Paulo Fernandes, and João Saraiva. 2017. Energy Efficiency across Programming Languages: How Do Energy, Time, and Memory Relate?.

In Proceedings of 2017 ACM SIGPLAN International Conference on Software Language Engineering (SLE’17). ACM, New York, NY, USA, 12 pages. https://doi.org/10.1145/3136014.3136031

Page 4: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 4

Related work

Rui Pereira, Marco Couto, Francisco Ribeiro, Rui Rua, Jácome Cunha, João Paulo Fernandes, and João Saraiva. 2017. Energy Efficiency across Programming Languages: How Do Energy, Time, and Memory Relate?.

In Proceedings of 2017 ACM SIGPLAN International Conference on Software Language Engineering (SLE’17). ACM, New York, NY, USA, 12 pages. https://doi.org/10.1145/3136014.3136031

Page 5: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 5

C++ design goals ● Type safety: strong type system● Resource safety: resource != memory

– RAII● Performance

– High performance– Low energy consumption

● Predictable run-time behavior– No virtual machine– No garbage collector

● Learnability– From expert friendly to novice friendly– Readable

Page 6: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 6

Roots of C++

FORTRAN SIMULA67

ALGOL68ALGOL

ASSEMBLY BCPL C

C++

Efficiency

Abstraction

Page 7: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 7

Memory layout of C++

Page 8: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 8

Execution of C++

Page 9: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 9

C++11● Core language improvements

– Rvalue references and move semantics– Constexpr– New memory model, thread locals– Better type inference (auto, decltype … )– Lambda functions, range based for– Initializer lists, uniform initialization, delegated constructors– Template aliases, variadic templates, user defined literals– Override, final, strongly typed enums, static assert, attributes– Right angle bracket!!! vector<list<int>>

● Libraries (mostly from Boost)– Hash tables (unordered_...)– Smart pointers (but unique_ptr instead of scoped_ptr)– Function objects and wrappers, Tuple, Array, Regular

expressions– Type traits

Page 10: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 10

C++14 ● Core language improvements

– Lambda (generalized lambda capture, generic lambda) – Constexpr extended– Generalized return type deduction– Binary literals and digit separators– decltype(auto)– Variable templates

Page 11: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 11

C++17 ● Language features

– Fold expressions– Template argument deduction for class templates– Constexpr if – Attributes, e.g. [[nodiscard]] (but std::remove() )– Structured binding

● New libraries– Filesystem– Utils (any, variant, optional, string_view, ...)

● Deprecated items– Trigraphs, register, auto_ptr– operator++(bool)– Old exception specification void foo() throw();

Page 12: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 12

C++20 ● Language features

– Concepts– Coroutins– Contracts– Further constexpr extensions – Modules– Ranges– operator<=>

● New libraries– Span– Calendar, timezone– … lots more

Page 13: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 13

Complexity grows

Page count of C++ standard

(by Bartłomiej Filipek: How to Stay Sane With Modern C++)

https://dzone.com/articles/how-to-stay-sane-with-modern-c

Page 14: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 14

Strict aliasing

Page 15: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 15

int f(int x, int y){ x = 0; y = 1; return x;}

Strict aliasing

Page 16: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 16

int f(int x, int y){ x = 0; y = 1; return x;}

Strict aliasing

Page 17: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 17

int f(int *xp, int *yp){ *xp = 0; *yp = 1; return *xp;}

Strict aliasing

Page 18: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 18

int f(int *xp, long *yp){ *xp = 0; *yp = 1; return *xp;}

Strict aliasing

Page 19: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 19

● Aliasing has negative effect on code optimization● Strict aliasing allows extra optimization posibilities● Using strong types have negative run time overhead● Using values instead of pointers / references may have negative overhead

Strict aliasing

Page 20: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 20

Move semantics

Page 21: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 21

● C++ has value semantics– Clear separation of memory areas– Significant performance loss when copying large objects– This led to improper use of (smart) pointers– … or template metaprogramming (expression templates)

C++ has value semantic

Page 22: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 22

● C++ has value semantics– Clear separation of memory areas– Significant performance loss when copying large objects– This led to improper use of (smart) pointers– … or template metaprogramming (expression templates)–

● Java

x = y;

C++ has value semantic

Page 23: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 23

● C++ has value semantics– Clear separation of memory areas– Significant performance loss when copying large objects– This led to improper use of (smart) pointers– … or template metaprogramming (expression templates)–

● Java

x = y;

C++ has value semantic

Page 24: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 24

● C++ has value semantics– Clear separation of memory areas– Significant performance loss when copying large objects– This led to improper use of (smart) pointers– … or template metaprogramming (expression templates)–

● Java

x = y;

● C++

x = y;

C++ has value semantic

Page 25: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 25

● C++ has value semantics– Clear separation of memory areas– Significant performance loss when copying large objects– This led to improper use of (smart) pointers– … or template metaprogramming (expression templates)–

● Java

x = y;

● C++

x = y;

C++ has value semantic

Page 26: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 26

Copy semanticsclass Array {public: Array( ); Array (const Array&); Array& operator=(const Array&); Array& operator+=(const Array&); ~ Array ( );private: double *val;};Array operator+(const Array& left, const Array& right){ Array res = left; res += right; return res;}

void f(){ Array b, c, d; … Array a = b + c + d;}

Page 27: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 27

class Array {public: Array( ); Array (const Array&); Array& operator=(const Array&); Array& operator+=(const Array&); ~ Array ( );private: double *val;};Array operator+(const Array& left, const Array& right){ Array res = left; res += right; return res;}

void f(){ Array b, c, d; … Array a = b + c + d;}

Copy semantics

Page 28: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 28

class Array {public: Array( ); Array (const Array&); Array& operator=(const Array&); Array& operator+=(const Array&); ~ Array ( );private: double *val;};Array operator+(const Array& left, const Array& right){ Array res = left; res += right; return res;}

void f(){ Array b, c, d; … Array a = b + c + d;}

Copy semantics

Page 29: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 29

class Array {public: Array( ); Array (const Array&); Array& operator=(const Array&); Array& operator+=(const Array&); ~ Array ( );private: double *val;};Array operator+(const Array& left, const Array& right){ Array res = left; res += right; return res;}

void f(){ Array b, c, d; … Array a = b + c + d;}

Copy semantics

Page 30: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 30

class Array {public: Array( ); Array (const Array&); Array& operator=(const Array&); Array& operator+=(const Array&); ~ Array ( );private: double *val;};Array operator+(const Array& left, const Array& right){ Array res = left; res += right; return res;}

void f(){ Array b, c, d; … Array a = b + c + d;}

Copy semantics

Page 31: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 31

Page 32: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 32

● Move semantics– Instead of copying, reusing the resources– Leave the other object in a valid, unspecified, destructible state– Rule of three becomes rule of five (or rule of one)– All standard library components has been extended

● Backward compatibility– If we implemented the old-style member functions with lvalue reference

but do not implement the rvalue reference overloading versions we keep the old behavior -> gradually shift to move semantics.

● Serious performance gain– Except some RVO situations

Move semantics

Page 33: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 33

class Array {public: Array( ); Array (const Array&); Array& operator=(const Array&); Array& operator+=(const Array&); ~ Array ( );private: double *val;};Array operator+(const Array& left, const Array& right){ Array res = left; res += right; return res;}

void f(){ Array b, c, d; … Array a = b + c + d;}

Move semantics

Page 34: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 34

class Array {public: Array( ); Array (const Array&); Array& operator=(const Array&); Array& operator+=(const Array&); ~ Array ( );private: double *val;};Array operator+(const Array& left, const Array& right){ Array res = left; res += right; return res;}

void f(){ Array b, c, d; … Array a = b + c + d;}

Move semantics

Page 35: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 35

class Array {public: Array( ); Array (const Array&); …};Array operator+(const Array& left, const Array& right){ Array res = left; res += right; return res;}Array operator+(Array&& left, const Array& right){ left += right; return std::move(left);}void f(){ Array b, c, d; … Array a = b + c + d;}

Move semantics

Page 36: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 36

class Array {public: Array ( ); Array (const Array&); Array (Array&&); Array& operator=(const Array&); Array& operator=(Array&&); ~ Array ( );private: double *val;};

Array operator+(const Array& left, const Array& right);Array operator+(Array&& left, const Array& right);

void f(){ Array b, c, d; … Array a = b + c + d;}

Move semantics

Page 37: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 37

Exception specification

Page 38: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 38

template <class T>

class vector{public: // usual operations

void push_back(cons T && );

void pop_back( );

// ...private: // usual implementation with 3 pointers T* buffer;

T* size;

T* end;

};

Vector

Page 39: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 39

template <class T>

class vector{public: // usual operations

void push_back(cons T && );

void pop_back( );

// ...private: // usual implementation with 3 pointers T* buffer;

T* size;

T* end;

};

Vector

Page 40: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 40

template <class T>

class vector{public: // usual operations

void push_back(cons T && );

void pop_back( );

// ...private: // usual implementation with 3 pointers T* buffer;

T* size;

T* end;

};

Vector

Page 41: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 41

template <class T>

class vector{public: // usual operations

void push_back(cons T && );

void pop_back( );

// ...private: // usual implementation with 3 pointers T* buffer;

T* size;

T* end;

};

Vector

Page 42: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 42

#include <iostream>#include <vector>

struct S{ S() : id(++cnt) { std::cout << "S() "; } S(const S& rhs) : id(rhs.id) { std::cout << "copyCtr "; } S(S&& rhs) : id(std::move(rhs.id)) { std::cout << "moveCtr "; } S& operator=(const S& rhs) { id = rhs.id; std::cout << "copy= "; return *this; } S& operator=(S&& rhs) { id = std::move(rhs.id); std::cout << "move= "; return *this; } int id; static int cnt;};int S::cnt = 0;

int main() { std::vector<S> sv(5); sv.push_back(S());

for (std::size_t i = 0; i < sv.size(); ++i) std::cout << sv[i].id << " "; std::cout << '\n'; }

Exception specification

Page 43: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 43

#include <iostream>#include <vector>

struct S{ S() : id(++cnt) { std::cout << "S() "; } S(const S& rhs) : id(rhs.id) { std::cout << "copyCtr "; } S(S&& rhs) : id(std::move(rhs.id)) { std::cout << "moveCtr "; } S& operator=(const S& rhs) { id = rhs.id; std::cout << "copy= "; return *this; } S& operator=(S&& rhs) { id = std::move(rhs.id); std::cout << "move= "; return *this; } int id; static int cnt;};int S::cnt = 0;

int main() { std::vector<S> sv(5); sv.push_back(S());

for (std::size_t i = 0; i < sv.size(); ++i) std::cout << sv[i].id << " "; std::cout << '\n'; }

$ g++ -std=c++11 && ./a.out

S() S() S() S() S() S() moveCtr copyCtr copyCtr copyCtr copyCtr copyCtr 1 2 3 4 5 6

Exception specification

Page 44: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 44

#include <iostream>#include <vector>

struct S{ S() : id(++cnt) { std::cout << "S() "; } S(const S& rhs) : id(rhs.id) { std::cout << "copyCtr "; } S(S&& rhs) : id(std::move(rhs.id)) { std::cout << "moveCtr "; } S& operator=(const S& rhs) { id = rhs.id; std::cout << "copy= "; return *this; } S& operator=(S&& rhs) { id = std::move(rhs.id); std::cout << "move= "; return *this; } int id; static int cnt;};int S::cnt = 0;

int main() { std::vector<S> sv(5); sv.push_back(S());

for (std::size_t i = 0; i < sv.size(); ++i) std::cout << sv[i].id << " "; std::cout << '\n'; }

$ g++ -std=c++11 && ./a.out

S() S() S() S() S() S() moveCtr copyCtr copyCtr copyCtr copyCtr copyCtr 1 2 3 4 5 6

Exception specification

Page 45: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 45

#include <iostream>#include <vector>

struct S{ S() : id(++cnt) { std::cout << "S() "; } S(const S& rhs) : id(rhs.id) { std::cout << "copyCtr "; } S(S&& rhs) noexcept : id(std::move(rhs.id)) { std::cout << "moveCtr "; } S& operator=(const S& rhs) { id = rhs.id; std::cout << "copy= "; return *this; } S& operator=(S&& rhs) noexcept { id = std::move(rhs.id); std::cout << "move= "; return *this; } int id; static int cnt;};int S::cnt = 0;

int main() { std::vector<S> sv(5); sv.push_back(S());

for (std::size_t i = 0; i < sv.size(); ++i) std::cout << sv[i].id << " "; std::cout << '\n'; }

Exception specification

Page 46: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 46

#include <iostream>#include <vector>

struct S{ S() : id(++cnt) { std::cout << "S() "; } S(const S& rhs) : id(rhs.id) { std::cout << "copyCtr "; } S(S&& rhs) noexcept : id(std::move(rhs.id)) { std::cout << "moveCtr "; } S& operator=(const S& rhs) { id = rhs.id; std::cout << "copy= "; return *this; } S& operator=(S&& rhs) noexcept { id = std::move(rhs.id); std::cout << "move= "; return *this; } int id; static int cnt;};int S::cnt = 0;

int main() { std::vector<S> sv(5); sv.push_back(S());

for (std::size_t i = 0; i < sv.size(); ++i) std::cout << sv[i].id << " "; std::cout << '\n'; }

$ g++ -std=c++11 && ./a.out

S() S() S() S() S() S()moveCtr moveCtr moveCtr moveCtr moveCtr moveCtr 1 2 3 4 5 6

Exception specification

Page 47: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 47

#include <iostream>#include <vector>

#include <algorithm>

struct S{ S() : id(++cnt) { std::cout << "S() "; } S(const S& rhs) : id(rhs.id) { std::cout << "copyCtr "; } S(S&& rhs) noexcept : id(std::move(rhs.id)) { std::cout << "moveCtr "; } S& operator=(const S& rhs) { id = rhs.id; std::cout << "copy= "; return *this; } S& operator=(S&& rhs) noexcept { id = std::move(rhs.id); std::cout << "move= "; return *this; } int id; static int cnt;};int S::cnt = 0;

int main() { std::vector<S> v1(5); std::vector<S> v2(5); std::move( v1.begin(), v1.end(), v2.begin());}

$ g++ -std=c++11 && ./a.out

S() S() S() S() S() S() S() S() S() S() S() S()

move= move= move= move= move=

std::move algorithm

Page 48: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 48

#include <iostream>#include <vector>

#include <algorithm>#include <iterator>

struct S{ S() : id(++cnt) { std::cout << "S() "; } S(const S& rhs) : id(rhs.id) { std::cout << "copyCtr "; } S(S&& rhs) noexcept : id(std::move(rhs.id)) { std::cout << "moveCtr "; } S& operator=(const S& rhs) { id = rhs.id; std::cout << "copy= "; return *this; } S& operator=(S&& rhs) noexcept { id = std::move(rhs.id); std::cout << "move= "; return *this; } int id; static int cnt;};int S::cnt = 0;

int main() { std::vector<S> v1(5); std::vector<S> v2; std::move( v1.begin(), v1.end(), back_inserter(v2));}

$ g++ -std=c++11 && ./a.out

S() S() S() S() S() S()

moveCtr moveCtr moveCtr moveCtr moveCtrmoveCtr moveCtr moveCtr moveCtr moveCtrmoveCtr moveCtr

std::move algorithm

Page 49: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 49

#include <iostream>#include <vector>

#include <algorithm>#include <iterator>

struct S{ S() : id(++cnt) { std::cout << "S() "; } S(const S& rhs) : id(rhs.id) { std::cout << "copyCtr "; } S(S&& rhs) noexcept : id(std::move(rhs.id)) { std::cout << "moveCtr "; } S& operator=(const S& rhs) { id = rhs.id; std::cout << "copy= "; return *this; } S& operator=(S&& rhs) noexcept { id = std::move(rhs.id); std::cout << "move= "; return *this; } int id; static int cnt;};int S::cnt = 0;

int main() { std::vector<S> v1(5); std::vector<S> v2; v2.reserve(5); std::move( v1.begin(), v1.end(), back_inserter(v2));}

$ g++ -std=c++11 && ./a.out

S() S() S() S() S() S()

moveCtr moveCtr moveCtr moveCtr moveCtr

std::move algorithm

Page 50: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 50

● Move semantics– Instead of copying, reusing the resources– Leave the other object in a valid, unspecified, destructible state– Rule of three becomes rule of five (or rule of one)– All standard library components has been extended

● Reverse compatibility– If we implemented the old-style member functions with lvalue reference

but do not implement the rvalue reference overloading versions we keep the old behavior -> gradually shift to move semantics.

● Serious performance gain– Except some RVO situations

Move semantics

Page 51: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 51

Undefined behavior

void f(){ int i = 1; std::cout << i << ++i;}

Page 52: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 52

Undefined behavior

void f(){ int i = 1; std::cout << i << ++i;}

$ ./a.out12

Page 53: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 53

Undefined behavior

void f(){ int i = 1; std::cout << i << ++i;}

$ ./a.out22

Page 54: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 54

Undefined behavior

void f(){ int i = 1; std::cout << i << ++i;}

$ ./a.out12

Page 55: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 55

cout i i

<<

<<

++

Undefined behavior

void f(){ int i = 1; std::cout << i << ++i;}

$ ./a.out22

Page 56: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 56

cout i i

<<

<<

++?

Undefined behavior

void f(){ int i = 1; std::cout << i << ++i;}

$ ./a.out22

Page 57: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 57

Undefined behavior

int f(int x){ int i; // not initialized if ( x < 0 ) i = 1; return i;}

Page 58: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 58

Constant evaluation

Page 59: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 59

Constant evaluation

int f(){ int sum = 0; for ( int i = 0; i < 100; ++i) sum += i; return sum;}

Page 60: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 60

Constant evaluation

int f(int n){ int sum = 0; for ( int i = 0; i < n; ++i) sum += i; return sum;}

Page 61: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 61

Constant evaluation

int f(int i) { return i; }

int main() { const int c1 = 1; // initialized compile time const int c2 = 2; // initialized compile time const int c3 = f(3); // f() is not constexpr const int *ptr = &c2; return 0;}

Page 62: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 62

Constant evaluation

int f(int i) { return i; }

int main() { const int c1 = 1; // initialized compile time const int c2 = 2; // initialized compile time const int c3 = f(3); // f() is not constexpr const int *ptr = &c2; return 0;}

Page 63: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 63

Constant evaluation

int main() { const int ci = 10; int *ip = const_cast<int*>(&ci); ++*rpm; cout << ci << " " << *ip << endl; return 0;}

$ ./a.out 10 11

Page 64: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 64

Constant evaluation

include <cstdio>

size_t constexpr strlen(const char* str){ return *str ? 1 + length(str + 1) : 0;}

Page 65: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 65

Constant evaluation C++14

#include <iostream>

constexpr int strlen(const char *s){ const char *p = s; while ( '\0' != *p ) ++p; return p-s;}

Page 66: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 66

Constant evaluation C++17

std::visit([](auto&& arg) { using T = std::decay_t<decltype(arg)>; if constexpr (std::is_same_v<T, int>) std::cout << "int with value " << arg << '\n'; else if constexpr (std::is_same_v<T, long>) std::cout << "long with value " << arg << '\n'; else if constexpr (std::is_same_v<T, double>) std::cout << "double with value " << arg << '\n'; else if constexpr (std::is_same_v<T, std::string>) std::cout << "std::string with value " << std::quoted(arg); else static_assert(always_false<T>::value,"non-exhaustive visitor!");}, w);

Page 67: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 67

C++11 concurrency model

Page 68: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 68

Main memory (common)

CacheCache

CPU

CacheCache

CPU

CacheCache

CPU

CacheCache

CPU

CacheCache

CPU

Modern multicore hardware

Page 69: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 69

● Describes the interactions of threads through memory

● Describes well defined behavior

● Constraints compiler for code generation

● C++ memory model contract

– Programmer ensures that the program has no data race

– System guarantees sequentially consistent execution

C++11 memory model

Page 70: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 70

● Only minimal progress guaranties are given on threads:

– unblocked threads will make progress

– implementation should ensure that writes in a thread should be visible in other threads "in a finite amount of time".

● The A happens before B relationship:

– A is sequenced before B or

– A inter-thread happens before B

== there is a synchronization point between A and B

● Synchronization point:

– thread creation sync with start of thread execution

– thread completion sync with the return of join()

– unlocking a mutex sync with the next locking of that mutex

C++11 memory model

Page 71: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 71

● Memory location

– an object of scalar type

– a maximal sequence of adjacent bit-fields all having non-zero width

● Data race

A program contains data race if contains two actions in different threads, at least one is not "atomic" and neither happens before the other.

● Two threads of execution can update and access separate memory locations without interfering each others

C++11 memory model

Page 72: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 72

● Memory location

– an object of scalar type

– a maximal sequence of adjacent bit-fields all having non-zero width

● Data race == undefined behavior== undefined behavior

A program contains data race if contains two actions in different threads, at least one is not "atomic" and neither happens before the other.

● Two threads of execution can update and access separate memory locations without interfering each others

C++11 memory model

Page 73: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 73

● Sequential consistent (default behavior)

– Leslie Lamport, 1979

– Each threads are executed in sequential order

– The operations of each thread appear in this sequence for the other threads in that order

Sequential consistency

Page 74: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 74

std::mutex m;Data d;bool flag = false;

// thread 1 | // thread 2void Produce() | void Consume(){ | { | bool ready; d = ... | flag = true; | | | | bool ready = flag; | | | if ( ready ) use(d);} | }

Sequential consistency

Page 75: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 75

std::mutex m;Data d;bool flag = false;

// thread 1 | // thread 2void Produce() | void Consume(){ | { | bool ready; d = ... | flag = true; | | | | bool ready = flag; | | | if ( ready ) use(d);} | }

Sequential consistency

Page 76: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 76

std::mutex m;Data d;bool flag = false;

// thread 1 | // thread 2void Produce() | void Consume(){ | { | bool ready; d = ... | flag = true; | | | | bool ready = flag; | | | if ( ready ) use(d);} | }

Data race!

Sequential consistency

Page 77: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 77

std::mutex m;Data d;bool flag = false;

// thread 1 | // thread 2void Produce() | void Consume(){ | { m.lock(); | bool ready; d = ... | flag = true; | m.unlock(); | | m.lock(); | bool ready = flag; | m.unlock(); | | if ( ready ) use(d);} | }

Sequential consistency

Page 78: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 78

std::mutex m;Data d;bool flag = false;

// thread 1 | // thread 2void Produce() | void Consume(){ | { m.lock(); | bool ready; d = ... | flag = true; | m.unlock(); | | m.lock(); | bool ready = flag; | m.unlock(); | | if ( ready ) use(d);} | }

Synchronized with

Sequential consistency

Page 79: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 79

std::mutex m;Data d;bool flag = false;

// thread 1 | // thread 2void Produce() | void Consume(){ | { m.lock(); | bool ready; d = ... | flag = true; | m.unlock(); | | m.lock(); | bool ready = flag; | m.unlock(); | | if ( ready ) use(d);} | }

Happens before

Sequential consistency

Page 80: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 80

std::mutex m;Data d;std::atomic<bool> flag = false;

// thread 1 | // thread 2void Produce() | void Consume(){ | { m.lock(); | bool ready; d = ... | flag.store(true); | m.unlock(); | | m.lock(); | bool ready = flag.load(); | m.unlock(); | | if ( ready ) use(d);} | }

Sequential consistency

Page 81: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 81

int x, y;

// thread 1 | // thread 2 x = 1; | cout << y << ", ";y = 2; | cout << x << endl;

In C++03 not even Undefined Behavior

In C++11 Undefined Behavior

Sequential consistency

Page 82: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 82

std::atomic<int> x, y;

// thread 1 | // thread 2x.store(1); | cout << y.load() << ", ";y.store(2); | cout << x.load() << endl;

Equivalent to:

int x, y;mutex x_mutex, y_mutex;

// thread 1 | // thread 2 x_mutex.lock() | y_mutex.lock();x = 1; | cout << y << ", ";x_mutex.unlock() | y_mutex.unlock();y_mutex.lock() | x_mutex.lock();y = 2; | cout << x << endl;y_mutex.unlock() | x_mutex.unlock();

Sequential consistency

Page 83: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 83

std::atomic<int> x, y;x.store(0); y.store(0);

// thread 1 | // thread 2x.store(1); | cout << y.load() << ", ";y.store(2); | cout << x.load() << endl;

Result can be:

0 02 10 1// never prints: 2 0

Sequential consistency: atomics == atomic load/store + ordering

Sequential consistency

Page 84: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 84

● memory_order_seq_cst (default)

● memory_order_consume

● memory_order_acquire

● memory_order_release

● memory_order_acq_rel

● memory_order_relaxed

X86/x86_64 does not require additional instructions to implement acquire-release ordering

Other memory orders

Page 85: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 85

● Each memory location has a total modification order

– But this may be not observable directly

● Memory operations performed by

– The same thread and

– On the same memory location

are not reordered with respect of modification order

Relaxed order

Page 86: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 86

std::atomic<int> x, y;

// relaxed// thread 1 | // thread 2x.store(1, memory_order_relaxed); | cout << y.load(memory_order_relaxed) << ", ";y.store(2, memory_order_relaxed); | cout << x.load(memory_order_relaxed) << endl;

// Defined, atomic, but not ordered, result may be:0 02 10 12 0

//======================== read-modify-write ====================

std::atomic<int> x;

// relaxed// thread 1 int i = x.load();While ( ! x.compare_exchnge_weak( i, // expected value i+1, // desired value memory_order_relaxed ) );

x.fetch_add( 1, memory_order_relaxed);

Relaxed order

Page 87: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 87

● A store-release operation synchronizes with all load-acquire operations reading a stored value

● Operations preceding the store-release in the releasing thread happens before operations following the load-acquire

● On some platforms acquire-release is cheaper than sequention consistency

std::mutex m; Data d;std::atomic<bool> flag = false;

// thread 1 | // thread 2void Produce() | void Consume(){ | { d = ... | flag.store(true, | memory_order_release); | bool flag.load(memory_order_acquire); | if ( ready ) use(d);} | }

Acquire-release order

Page 88: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 88

● A store-release operation synchronizes with all load-acquire operations reading a stored value

● Operations preceding the store-release in the releasing thread happens before operations following the load-acquire

● On some platforms acquire-release is cheaper than sequention consistency

std::mutex m; Data d;std::atomic<bool> flag = false;

// thread 1 | // thread 2void Produce() | void Consume(){ | { d = ... | flag.store(true, | memory_order_release); | bool flag.load(memory_order_acquire); | if ( ready ) use(d);} | }

Acquire-release order

Page 89: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 89

● A store-release operation synchronizes with all load-acquire operations reading a stored value

● Operations preceding the store-release in the releasing thread happens before operations following the load-acquire

● On some platforms acquire-release is cheaper than sequention consistency

std::mutex m; Data d;std::atomic<bool> flag = false;

// thread 1 | // thread 2void Produce() | void Consume(){ | { d = ... | flag.store(true, | memory_order_release); | bool flag.load(memory_order_acquire); | if ( ready ) use(d);} | }

Acquire-release order

Page 90: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 90

// acquire-release// thread 1 | // thread 2x.store(1, memory_order_release); | cout << y.load(memory_order_acquire) << ", ";y.store(2, memory_order_release); | cout << x.load(memory_order_acquire) << endl;

// In C++11 Defined and the result can be: 0 02 10 1// never prints: 2 0, but can be faster than strict ordering.// results may be different in more complex programs

Acquire-release order

Page 91: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 91

● Operations preceding the store-release in the releasing thread happens before an operation X in the consuming thread where X has a data dependency on the loaded value

int d = 0;std::atomic<int *> ptr = std::nullptr;

// thread 1 | // thread 2void Produce() | void Consume(){ | { d = 42 | int *p; ptr.store(&x, | memory_order_release); | if (p=ptr.load(memory_order_consume)) | { | assert ( 42 == *p ); // true | assert ( 42 == d ); // DATA RACE | }} | }

Consume-release order

Page 92: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 92

● Operations preceding the store-release in the releasing thread happens before an operation X in the consuming thread where X has a data dependency on the loaded value

int d = 0;std::atomic<int *> ptr = std::nullptr;

// thread 1 | // thread 2void Produce() | void Consume(){ | { d = 42 | int *p; ptr.store(&x, | memory_order_release); | if (p=ptr.load(memory_order_consume)) | { | assert ( 42 == *p ); // true | assert ( 42 == d ); // DATA RACE | }} | }

Consume-release order

Page 93: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 93

● Operations preceding the store-release in the releasing thread happens before an operation X in the consuming thread where X has a data dependency on the loaded value

int d = 0;std::atomic<int *> ptr = std::nullptr;

// thread 1 | // thread 2void Produce() | void Consume(){ | { d = 42 | int *p; ptr.store(&x, | memory_order_release); | if (p=ptr.load(memory_order_consume)) | { | assert ( 42 == *p ); // true | assert ( 42 == d ); // DATA RACE | }} | }

Consume-release order

Page 94: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 94

Dead code optimization

Page 95: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 95

#include <memory.h>

void consume(char *);

void f(){ int i; char secret[BUFSIZE]; fgets( secret,v BUFSIZE, stdin); // use secret consume(secret); }

Dead code optimization

Page 96: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 96

#include <memory.h>

void consume(char *);

int main(){ int i; char secret[BUFSIZE]; fgets( secret,v BUFSIZE, stdin); // use secret consume(secret); // erase secret for security reasons memset(secret, 0, sizeof(secret)); // check secret for(i = 0; i < BUFSIZE; ++i) printf(“d”,secret[i]);}

Dead code optimization

Page 97: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 97

Dead code optimization

Page 98: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 98

#include <memory.h>

void consume(char *);

int main(){ int i; char secret[BUFSIZE]; fgets( secret,v BUFSIZE, stdin); // use secret consume(secret); // erase secret for security reasons memset(secret, 0, sizeof(secret)); }

Dead code optimization

Page 99: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 99

Dead code optimization

Page 100: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 100

Dead code optimization -O3

Page 101: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 101

#include <memory.h>

void consume(char *);

int main(){ void* (*fp)(void*,int,size_t); int i; fp = memset; char secret[BUFSIZE]; fgets( secret,v BUFSIZE, stdin); // use secret consume(secret); // erase secret for security reasons fp(secret, 0, sizeof(secret)); }

Dead code optimization

Page 102: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 102

Dead code optimization

Page 103: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 103

#include <memory.h>

void consume(char *);

volatile void* (*fp)(void*,int,size_t);

int main(){ int i; fp = memset; char secret[BUFSIZE]; fgets( secret,v BUFSIZE, stdin); // use secret consume(secret); // erase secret for security reasons fp(secret, 0, sizeof(secret)); }

Dead code optimization

Page 104: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 104

Dead code optimization

Page 105: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 105

#include <memory.h>

void consume(char *);

int main(){ int i; char secret[BUFSIZE]; fgets( secret,v BUFSIZE, stdin); // use secret consume(secret); // erase secret for security reasons memset_s(secret, sizeof(secret), 0, sizeof(secret)); }

Dead code optimization

Page 106: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 106

Dead code optimization

Page 107: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 107

Summary

● C++ gives you full control over resources

– No virtual machine, no interpretation

● Compilers can make extreme optimizations● Programmer can destroy these opportunities

– Unnecessary copies– False optimizations– Aliasing

● Programmer can provide optimizations

– Writing “not too clever” code– Using strong types– Avoid aliasing– Choosing the right memory model

Page 108: SAVE THE EARTH, PROGRAM IN C++! · 2019. 5. 9. · 2019.05.10. Porkoláb: Save the Earth, Program in C++ 32 Move semantics – Instead of copying, reusing the resources – Leave

2019.05.10. Porkoláb: Save the Earth, Program in C++ 108

Q&A

Zoltán PorkolábEricsson / Eötvös Loránd Universityhttp://gsd.web.elte.hu