Deprecated: The each() function is deprecated. This message will be suppressed on further calls in /home/zhenxiangba/zhenxiangba.com/public_html/phproxy-improved-master/index.php on line 456 Stroustrup: ESC99 Talk
Standard C++ for Embedded Systems Programming
Here are the slides I used for my keynote at ESC'99 in Chicago, March 2 1999.
Standard C++ for Embedded Systems Programming
Bjarne Stroustrup
AT&T; Labs
Florham Park, NJ 07932, USA
bs@research.att.com
http://www.research.att.com/~bs
Abstract:
To ease design, implementation, and maintenance of software, we want
to raise the level of abstraction in our code. What does Standard C++
offer to make this possible without loss of performance or predictability?
C++
- is a better C
- supports data abstraction
- supports object-oriented programming
- supports generic programming
(it is a ``a multi-paradigm language'')
Work at the highest level that you can afford
- shorter source code
- clearer source code
- easier maintenance
- better source-level tool support
But what does "afford" mean?
- run-time
- storage overhead
- predictability
- development time
- maintenance cost
- tool support
- programmer skill
- ...
C++ aims:
efficiency *and* abstraction
- not "efficiency *or* abstraction"
- not "efficient if you limit yourself to C style"
- not "if you use my experimental optimizer"
- now
not "in a few years when magic happens"
C++ has always been used for embedded applications:
- device drivers
- network layers
- real time OSs
- monitoring equipment
- dash boards
- welding robots (and other robots)
- DSP
- ...
("always" == "from 1982 or so")
Standard C++
- ISO/IEC-14882 standard ratified 1998
- the result of a consensus process
Canada, France, Germany, Japan, UK, US, ...
AT&T;, Borland, Ericsson, IBM, HP, Intel, MS
Siemens, Sun, ...
hundreds of individuals
- serves the needs of diverse communities
- eases cooperation / understanding
- room for growth
- wide support
There is no substitute for
- intelligence
- experience
- taste
- hard work
Zero-overhead rule:
``What you don't use, you don't pay for''
or
``There is no way of writing equivalent C code
that runs faster or generates smaller code''
- but does implementations meet it?
- Classes (yes)
- Virtual functions (yes)
- Exceptions (can, rarely do)
expect 5% to 20% space and/or time overhead
- templates (yes)
- libraries (some do, some don't - know your libraries)
Crucial point: Function call
C++ C
non-virtual member function
p->f(1) 1.72s f(p,1) 1.67s
p.f(1) 1.47s f(&s;,1) 1.67s
virtual fct indirect fct
p->g(1) 1.47s g(&s;,1) 1.46s
x.g(1) 1.47s g(p,1) 1.47s
static member function
X::h(1) 1.72s h(1) 1.72s
inline fct macro
p->k(1) 0.66s K(p,1) 0.67s
x.k(1) 0.46s K(&s;,1) 0.46s
That's good enough for anyone who can live with C.
(implementations vary, check yours)
Concrete types:
small heavily-used abstractions are very common
design them carefully
support them well
- convenience
- efficiency
the mundane is statistically more important than the advanced
The ideal candidate for a class:
frequently used
elegant interface matters
efficiency matters
represent concept that might be useful elsewhere
in other programs
on other systems
simple interface
many possible implementations
Classes:
class queue {
public:
put(message*);
message* get();
// ...
private:
// representation
};
void filter(queue& in, queue& out)
{
while (message* m = in.get()) {
// do something
put(m);
}
}
inline message* queue::get()
{
if (no_of_elements() == 0) return underflow();
// ...
}
representation available (=> run-time efficiency)
- inlining
- true local variables
no space overhead
layout compatibility when desired
Inlining:
In theory, compilers are better at inlining
In reality, programmers can do better with "inline" declarations
- better pipelining
- more opportunities for optimizers
- less code for simple functions
There are things you just can't do in a machine-independent way,
specialized instructions (e.g. vector operations,
I/O instructions, memory mapping instructions),
so use assembler:
inine int isr_hot_flag() // i960
{
register unsigned tmp;
asm("modpc 0, 0, %0" : "=r" (tmp));
return tmp & 0x2000;
}
In emergencies, asm() can also be used for hand optimization
Abstract classes for defining interfaces:
class Device {
// no representation (=> typically no constructor)
public:
virtual int open(int opt) =0; // pure virtual
virtual int close(int opt) =0;
virtual int read(char* p, int n) =0;
// ...
virtual ~Device(); // virtual destructor
};
Abstract classes:
representation unavailable to optimizers
- usually allocate using new
- use virtual functions
- access through pointers and references
different representations can coexist
- no recompilation of user code after representation change
Abstract classes allow many different implementations:
class Dev1 : public Device {
public:
int open(int opt);
int close(int opt);
int read(char* p, int n);
// ...
private:
// representation
};
class Dev2 : public Device {
// ...
};
Polymorphic code even useful without dynamic memory allocation
Dev1 d1(args1);
Dev2 d2(args2);
void f(Device& d)
{
char buf[max];
int n = d.read(buf,max);
// ...
};
void g()
{
f(d1);
f(d2);
}
Free store
some embedded systems can afford it, many can't
- time
- space
- predictability
- memory exhaustion
- several memory types/pools (placement)
Automatic garbage collection possible where affordable:
http://www.hpl.hp.com/personal/Hans_Boehm/gc
Special-purpose memory allocation:
new X; // use default allocator
// or class-specific allocator
new(&buffer;[3]) X; // place X in buffer[3]
new(Shared) X; // allocated from Shared memory
Exception handling;
- uniform mechanism for signalling errors
- reasonably simple
try { ... } catch(some_error) { ... }
throw some_error();
- potentially efficient
- not suitable for all embedded applications
- can be disabled in most implementations
Predictability:
basic operations perform in fixed time, except
exception throw
default free store allocation
Can programmers predict performance?
yes, but not without
- being experienced and careful and/or
- using profilers
(just like for *every* other language - including assembler)
Templates:
Needed for efficient and typesafe containers.
no run-time overhead
static type safety
- eliminates many casts
- eliminates many macros
memory overhead if carelessly used
Templates:
Almost every standard library facility is template based
- stream i/o
- strings
- containers
- algorithms
- complex numbers
- vectors with numeric operations
Standard library templates:
Containers:
list, vector, priority_queue, map, ...
Algorithms:
sort, binary_search, partial_sort
find, find_if
copy, unique_copy
for_each, transform
accumulate
...
Note: type safe (no casts), optimal run time,
be careful about code replication
Simple run-time efficiency test:
read a lot of input,
do a bit with each element,
store each element in memory
do a bit with the set of elements
I/O plus computation
(if necessary, memory could be pre-allocated)
vector buf;
fstream fin(file,ios::in);
double d;
while(fin>>d) buf.push_back(d); // read and store
sort(buf.begin(),buf.end());
// ...
Read, sort, and write floating-point numbers
unoptimized optimized
elements C++ C C/C++ ratio C++ C C/C++ ratio
500,000 3.5 6.1 1.74 2.5 5.1 2.04
5,000,000 38.4 172.6 4.49 27.4 126.6 4.62
(for details, see May issue of C and C++ Users' Journal)
How could that be done?
- templates for generality
- clean, simple algorithms
- inlining for efficiency
Does C++ always run this much faster than C?
- of course not
- implementations differ (library and language)
- often there is no scope for major improvements
You don't need "genius programmers" to use Standard C++
- simple execution model
- simple object model
- choose techniques and language features to suit problem
- no prize for using the largest number of features
- use frameworks and foundation libraries as appropriate
- much easier to use than to design/implement
Weaknesses (that can be strengths)
no standard
-concurrency
- persistence
- large standard execution environment (e.g. OS services)
- GUI
Standard C++
- well specified
not proprietary (ISO, ANSI, ...)
long-term stability (5 year revision cycle)
- multiple implementations/suppliers
- efficient
- comprehensive
- easier to learn than previous versions
For links, see http://www.research.att.com/~bs