logo资料库

C++ High Performance A Boost and optimize the performance of you C++17 code.pdf

第1页 / 共481页
第2页 / 共481页
第3页 / 共481页
第4页 / 共481页
第5页 / 共481页
第6页 / 共481页
第7页 / 共481页
第8页 / 共481页
资料共481页,剩余部分请下载后查看
Preface
Who this book is for
What this book covers
To get the most out of this book
Download the example code files
Conventions used
Get in touch
Reviews
A Brief Introduction to C++
Why C++?
Zero-cost abstractions
Programming languages and machine code abstractions
Abstractions in other languages
Portability
Robustness
C++ of today
The aim of this book
Expected knowledge of the reader
C++ compared with other languages
Competing languages and performance
Non-performance-related C++ language features
Value semantics
Const correctness
Object ownership and garbage collection in C++
Avoiding null objects using C++ references
Drawbacks of C++
Class interfaces and exceptions
Strict class interfaces
Error handling and resource acquisition
Preserving the valid state
Resource acquisition
Exceptions versus error codes
Libraries used in this book
Summary
Modern C++ Concepts
Automatic type deduction with the auto keyword
Using auto in function signatures
Using auto for variables
Const reference
Mutable reference
Forwarding reference
Conclusion
The lambda function
Basic syntax of a C++ lambda function
The capture block
Capture by reference versus capture by value
Similarities between a Lambda and a class
Initializing variables in capture
Mutating lambda member variables
Mutating member variables from the compiler's perspective
Capture all
Assigning C function pointers to lambdas
Lambdas and std::function
Assigning lambdas to std::functions
Implementing a simple Button class with std::function
Performance consideration of std::function
An std::function cannot be inlined
An std::function heap allocates and captures variables
Invoking an std::function requires a few more operations than a lambda
The polymorphic lambda
Creating reusable polymorphic lambdas
Const propagation for pointers
Move semantics explained
Copy-construction, swap, and move
Copy-constructing an object
Swapping two objects
Move-constructing an object
Resource acquisition and the rule of three
Implementing the rule of three
Constructor
Limitations of the rule of three
Avoiding copies without move semantics
Introducing move semantics
Named variables and r-values
Accept arguments by move when applicable
Default move semantics and the rule of zero
Rule of zero in a real code base
A note on empty destructors
A common pitfall - moving non-resources
Applying the && modifier to class member functions
Representing optional values with std::optional
Optional return values
Optional member variables
Sorting and comparing std::optional
Representing dynamic values with std::any
Performance of std::any
Summary
Measuring Performance
Asymptotic complexity and big O notation
Growth rates
Amortized time complexity
What to measure?
Performance properties
Performance testing – best practices
Knowing your code and hot spots
Profilers
Instrumentation profilers
Sampling profilers
Summary
Data Structures
Properties of computer memory
STL containers
Sequence containers
Vector and array
Deque
List and forward_list
The basic_string
Associative containers
Ordered sets and maps
Unordered sets and maps
Hash and equals
Hash policy
Container adaptors
Priority queues
Parallel arrays
Summary
A Deeper Look at Iterators
The iterator concept
Iterator categories
Pointer-mimicking syntax
Iterators as generators
Iterator traits
Implementing a function using iterator categories
Extending the IntIterator to bidirectional
Practical example – iterating floating point values within a range
Illustrated usage examples
Utility functions
How to construct a linear range iterator
Iterator usage example
Generalizing the iterator pair to a range
The make_linear_range convenience function
Linear range usage examples
Summary
STL Algorithms and Beyond
Using STL algorithms as building blocks
STL algorithm concepts
Algorithms operate on iterators
Implementing a generic algorithm that can be used with any container
Iterators for a range point to the first element and the element after the last
Algorithms do not change the size of the container
Algorithms with output require allocated data
Algorithms use operator== and operator< by default
Custom comparator function
General-purpose predicates
Algorithms require move operators not to throw
Algorithms have complexity guarantees
Algorithms perform just as well as C library function equivalents
STL algorithms versus handcrafted for-loops
Readability and future-proofing
Real-world code base example
Usage examples of STL algorithms versus handcrafted for-loops
Example 1 – Unfortunate exceptions and performance problems
Example 2 – STL has subtle optimizations even in simple algorithms
Sorting only for the data you need to retrieve
Use cases
Performance evaluation
The future of STL and the ranges library
Limitations of the iterators in STL
Introduction to the ranges library
Composability and pipeability
Actions, views, and algorithms
Actions
Views
Algorithms
Summary
Memory Management
Computer memory
The virtual address space
Memory pages
Thrashing
Process memory
Stack memory
Heap memory
Objects in memory
Creating and deleting objects
Placement new
The new and delete operators
Memory alignment
Padding
Memory ownership
Handling resources implicitly
Containers
Smart pointers
Unique pointer
Shared pointer
Weak pointer
Small size optimization
Custom memory management
Building an arena
A custom memory allocator
Summary
Metaprogramming and Compile-Time Evaluation
Introduction to template metaprogramming
Using integers as template parameters
How the compiler handles a template function
Using static_assert to trigger errors at compile time
Type traits
Type trait categories
Using type traits
Receiving the type of a variable with decltype
Conditionally enable functions based on types with std::enable_if_t
Introspecting class members with std::is_detected
Usage example of is_detected and enable_if_t combined
The constexpr keyword
Constexpr functions in a runtime context
Verify compile-time computation using std::integral_constant
The if constexpr statement
Comparison with runtime polymorphism
Example of generic modulus function using if constexpr
Heterogeneous containers
Static-sized heterogenous containers
The std::tuple container
Accessing the members of a tuple
Iterating std::tuple
Unrolling the tuple
Implementing other algorithms for tuples
Accessing tuple elements
Structured bindings
The variadic template parameter pack
An example of a function with variadic number of arguments
How to construct a variadic parameter pack
Dynamic-sized heterogenous containers
Using std::any as the base for a dynamic-size heterogenous container
The std::variant
Visiting variants
Heterogenous container of variants
Accessing the values in our variant container
Global function std::get
Real world examples of metaprogramming
Example 1 – Reflection
Making a class reflect its members
C++ libraries which simplifies reflection
Using the reflection
Evaluating the assembler output of the reflection
Conditionally overloading global functions
Testing reflection capabilities
Example 2 – Creating a generic safe cast function
Example 3 – Hash strings at compile time
The advantages of compile-time hash sum calculation
Implement and verify a compile-time hash function
Constructing a PrehashedString class
Forcing PrehashedString to only accept compile time string literals
Evaluating PrehashedString
Evaluating get_bitmap_resource() with PrehashedString
Summary
Proxy Objects and Lazy Evaluation
An introduction to lazy evaluation and proxy objects
Lazy versus eager evaluation
Proxy objects
Comparing concatenated strings using a proxy
Implementing the proxy
Performance evaluation
The r-value modifier
Assigning a concatenated proxy
Postponing an sqrt computation when comparing distances
A simple two-dimensional point class
The underlying mathematics
Implementing the DistProxy object
Expanding DistProxy to something more useful
Comparing distances with DistProxy
Calculating distances with DistProxy
Preventing the misuse of DistProxy
Performance evaluation
Creative operator overloading and proxy objects
The pipe operator as an extension method
The pipe operator
The infix operator
Further reading
Summary
Concurrency
Understanding the basics of concurrency
What makes concurrent programming hard?
Concurrency and parallelism
Time slicing
Shared memory
Data races
Mutex
Deadlock
Synchronous and asynchronous tasks
Concurrent programming in C++
The thread support library
Threads
Thread states
Protecting critical sections
Avoiding deadlocks
Condition variables
Returning data and handling errors
Tasks
Atomic support in C++
Using shared_ptr in a multithreaded environment
C++ memory model
Instruction reordering
Atomics and memory orders
Lock-free programming
Lock-free queue example
Performance guidelines
Avoid contention
Avoid blocking operations
Number of threads/CPU cores
Thread priorities
Thread affinity
False sharing
Summary
Parallel STL
Importance of parallelism
Parallel algorithms
Implementing parallel std::transform()
Naive implementation
Performance evaluation
Shortcomings of the naive implementation
Divide and conquer
Implementation
Performance evaluation
Implementing parallel std::count_if
Implementing parallel std::copy_if
Approach one – Use a synchronized write position
Inner function
Outer function
Approach two – Split algorithm into two parts
Part one – Copy elements in parallel into the destination range
Part two – Move the sparse range sequentially into a continuous range
Performance evaluation
Parallel STL
Execution policies
Sequenced policy
Parallel policy
Parallel unsequenced policy
Parallel modifications of algorithm
std::accumulate and std::reduce
std::transform_reduce
std::for_each
Parallelizing an index-based for-loop
Combining std::for_each with linear range
Simplifying construction via a wrapper
Executing STL algorithms on the GPU
GPU APIs and parallel operations
Programmable GPUs
Shader programs
STL algorithms and the GPU
Boost Compute
Basic concepts of Boost Compute
OpenCL
Initializing Boost Compute
Transfer a simple transform-reduce algorithm to Boost Compute
The algorithm in standard C++
Transforming the algorithm to Boost Compute
Adapting the circle struct for use with Boost Compute
Converting circle_area_cpu to Boost Compute
The BOOST_COMPUTE_FUNCTION macro
Implementing the transform-reduction algorithm on the GPU
Using predicates with Boost Compute
Using a custom kernel in Boost Compute
Box filter
Implementing the kernel
Parallelizing for two dimensions
Verify GPU computation on the CPU
Summary
Other Books You May Enjoy
Leave a review - let other readers know what you think
C++ High Performance Boost and optimize the performance of your C++17 code Viktor Sehr Björn Andrist 2
BIRMINGHAM - MUMBAI 3
C++ High Performance Copyright © 2018 Packt Publishing All rights reserved. No part of this book may be reproduced, stored in a retrieval system, or transmitted in any form or by any means, without the prior written permission of the publisher, except in the case of brief quotations embedded in critical articles or reviews. Every effort has been made in the preparation of this book to ensure the accuracy of the information presented. However, the information contained in this book is sold without warranty, either express or implied. Neither the author(s), nor Packt Publishing or its dealers and distributors, will be held liable for any damages caused or alleged to have been caused directly or indirectly by this book. Packt Publishing has endeavored to provide trademark information about all of the companies and products mentioned in this book by the appropriate use of capitals. However, Packt Publishing cannot guarantee the accuracy of this information. Commissioning Editors: Aaron Lazar Acquisition Editor: Denim Pinto Content Development Editors: Nikhil Borkar Technical Editor: Jijo Maliyekal Copy Editor: Safis Editing Project Coordinator: Vaidehi Sawant Proofreader: Safis Editing Indexers: Rekha Nair Graphics: Tania Dutta Production Coordinator: Arvindkumar Gupta First published: January 2018 Production reference: 1300118 Published by Packt Publishing Ltd. Livery Place 35 Livery Street Birmingham B3 2PB, UK. ISBN 978-1-78712-095-2 www.packtpub.com 4
mapt.io Mapt is an online digital library that gives you full access to over 5,000 books and videos, as well as industry leading tools to help you plan your personal development and advance your career. For more information, please visit our website. 5
Why subscribe? Spend less time learning and more time coding with practical eBooks and Videos from over 4,000 industry professionals Improve your learning with Skill Plans built especially for you Get a free eBook or video every month Mapt is fully searchable Copy and paste, print, and bookmark content 6
PacktPub.com Did you know that Packt offers eBook versions of every book published, with PDF and ePub files available? You can upgrade to the eBook version at www.PacktPub.com and as a print book customer, you are entitled to a discount on the eBook copy. Get in touch with us at service@packtpub.com for more details. At www.PacktPub.com, you can also read a collection of free technical articles, sign up for a range of free newsletters, and receive exclusive discounts and offers on Packt books and eBooks. 7
Foreword C++ stepped onto the stage in 1983 and hasn’t stopped reinventing itself for a single year since. It has gone from a single frontend language on top of C to a first-class citizen of the compiler world. Each new C++ standard has added substantial functionality, sometimes to excess. In the words of Stroustrup, “Within C++, there is a much smaller and cleaner language struggling to get out.” The problem, of course, is that the “smaller and cleaner language” to be found within C++ changes with situation. Mastering C++ is akin to mastering a multitude of domain-specific languages, each tailored to a specific use. The dialect that makes sense for embedded system is nonsensical for large enterprise applications, and the phrasing that powers a game engine is unbearable when applied to a word processor. C++ High Performance teaches you a C++ dialect for rapidly developing high-performance code. From C++11 onward, there have been a vast array of features in both the C++ language and the C++ STL that let you spend more time writing your application and less time handling implementation details. This is the focus of the book and where it shines. Each topic is framed in the larger context of application development and computer science. For the reader who needs to get up to speed with the latest C++ techniques on a short notice, this information provides the necessary landmarks to stay oriented. Specific examples, recipes, and logical progressions take you from a basic use of auto and all the way up to using Boost to transparently run your algorithms on the GPU via OpenCL. Fundamental issues around modern C++ (memory management and ownership, considerations of time and space, advance template usage, and others) are explained step by step so that, by the later chapters, the readers proceed into advanced territory with confidence. I have worked on a wide variety of projects—large and small, low level and managed, and some even in custom languages I designed and built—but C++ holds a special place in my heart. My first full-time job was writing C++ code for a game technology company in the early 2000s. I loved it, not least of all because a big part of the technology revolved around the reflection of the C++ code base into the editor and scripting language. Someone once described C++ as an octopus made by nailing extra legs onto a dog, and I spent a lot of time with a hammer making our code base do things that C++ was never intended to do. Yet, the octopus we ended up with was, in its own way, beautiful and very effective. C++ has evolved tremendously since those days, and it is my privilege to open the door for you as you walk into an exciting new world of possibilities. Viktor and Björn are brilliant and experienced developers with a remarkable pedigree, and they have a lot of great things in store for you. Ben Garney CEO, The Engine Company 8
分享到:
收藏