Re: is C necessarily faster than C++

jplevyak@pink-panther.cs.uiuc.edu (John B. Plevyak)
Sat, 29 Apr 1995 00:46:26 GMT

          From comp.compilers

Related articles
[11 earlier articles]
Re: is C necessarily faster than C++ cliffc@crocus.hpl.hp.com (1995-04-17)
Re: is C necessarily faster than C++ gardner@pink-panther.cs.uiuc.edu (1995-04-28)
Re: is C necessarily faster than C++ urs@engineering.ucsb.edu (1995-04-28)
Re: is C necessarily faster than C++ quanstro@hp-demo1.minerva.bah.com (1995-04-28)
Re: is C necessarily faster than C++ beard@cs.ucdavis.edu (Patrick C. Beard) (1995-04-28)
is C necessarily faster than C++ ka@socrates.hr.att.com (1995-04-28)
Re: is C necessarily faster than C++ jplevyak@pink-panther.cs.uiuc.edu (1995-04-29)
Re: is C necessarily faster than C++ tmb@netcom.com (1995-04-29)
Re: is C necessarily faster than C++ jdean@pysht.cs.washington.edu (1995-05-09)
Re: is C necessarily faster than C++ calder@mumble.cs.Colorado.EDU (1995-05-09)
Re: is C necessarily faster than C++ schow@bnr.ca (stanley (s.t.h.) chow) (1995-05-09)
Re: is C necessarily faster than C++ mike@vlsivie.tuwien.ac.at (1995-05-04)
Re: is C necessarily faster than C++ bill@amber.ssd.hcsc.com (1995-05-16)
[4 later articles]
| List of all articles for this month |
Newsgroups: comp.compilers
From: jplevyak@pink-panther.cs.uiuc.edu (John B. Plevyak)
Summary: data + commentary on C++ and OO in general
Keywords: C++, OOP, optimize, C
Organization: University of Illinois at Urbana
Date: Sat, 29 Apr 1995 00:46:26 GMT

OO programs are not inherently inefficient. C++, however, has
certain features which can inhibit optimization. As with C, it is
important to understand the optimizations your compiler is capable
of, and the features of the language which can inhibit these
optimizations.


We did a study, part of which compared the efficiency of a pure
(concurrent) object-oriented language with C and C++ using the
Livermore Loops. (POPL`95: Obtaining Sequential Efficiency for
Concurrent Object-Oriented Languages)


The results confirmed what Urs and Kenneth have said, namely that:


1) Current C++ compilers based on C optimizers are not adequate for C++.


2) Object-oriented programs *can* be compiled so that they are
      essentially the same as their non-object-oriented counterparts.


The object-oriented codes implemented multi-dimension arrays
by linearizing the indexes in the array access methods (as
in Kenneth's example).


We compared with our compiler with C and C++ (with virtual and
non-virtual function). The C/C++ compiler was GCC/G++ at -O2, the
machine was a Sparc2. To summarize the results:


Code Language Performance (relative to C)
-------------- -------- ---------------------------
Kernel 12 (1D) C 1.0
Kernel 12 (1D) CA (ours) ~1.0
Kernel 12 (1D) C++ ~1.0 * note 1
Kernel 12 (1D) C++ (virtual) ~0.3 * note 2


Kernel 21 (2D) C 1.0
Kernel 21 (2D) CA (ours) ~1.0 * note 3
Kernel 21 (2D) C++ ~0.2 * note 4
Kernel 21 (2D) C++ (virtual) ~0.13 * note 5


note 1: the C++ compiler does a reasonable job with C++ code when
only simple inlining is required.


note 2: however, it cannot inline virtual functions effectively


note 3: we used dynamic alias information to load the
lower dimensions into a register


note 4: the C++ compiler was not able to


note 5: virtual functions make the problem worse


-- PROBLEMS WITH C++ and OO in gneral


One might argue that the Livermore Loops are not very object-oriented
(and you would be right), but even these simple codes point out the
main problems with compiling OO programs:


1) Aliasing


2) Virtual Functions


ALIASING
--------


Object oriented programs have a tendency to scope memory locations.
For example, in the virtual function foo() below:


class A {
    int a;
    virtual int foo() { a++; bar(); return a++; }
};




The variable "a" is scoped, but it could be an aliased heap location.
Without information about bar(), the compiler must spill "a" to memory
before the call (and similarly around writes through many pointers and
arrays in C).


This problem is exacerbated by inlining. In Kenneth's example:


> add(const struct matinfo *a, const struct matinfo *b) {
> int i, j;
>
> for (i = 1 ; i <= a->dim1 ; i++) {
> for (j = 1 ; j <= a->dim2 ; j++) {
> b->addr[(i - 1) * b->dim2 + (j - 1)] +=
> a->addr[(i - 1) * a->dim2 + (j - 1)];
> }
> }
> }


dim2 has been scoped in a loop (perhaps without the user of the matrix
library being aware).


Aliasing can be addressed through several means, most notably
annotations (a simple example is the "register" storage class in C)
and analysis. However, C++ has some features which complicate
analysis, most notably casting, separate compilation and pointers into
the middle of objects.


VIRTUAL FUNCTIONS
-----------------


Object-oriented programs tend to have very small functions and to make
lots of function calls. Virtual functions are both more expensive
than regular function and *more importantly* prevent inlining (since
the functions are now smaller than they would be in C, the only way
to get back to C-like code would be to inline some of them).


Virtual functions can be inlined through a number of techniques:


Generally:


  -- Speculative Inlining (Prediction/Splitting): insert an inline test
        for the 'most likely' class:


        if (x->class_id == CLASS_A) {
            ... inline code x->bar() ...
        } else x->bar()




-- Specialiation (Customization/Cloning): replicate methods for
      particular situations:


      class A {
          virtual int bar() { ... this->foo() .. }
          virtual int foo() { ... code block 1 .. }
          ...


      class B : A {
          virtual int foo() { ... code block 2 .. }
          ...




      If we replicate bar() into class B we can now inline A::foo()
      into A::bar() and B:foo() into B:bar().


Unfortunately, these optimizations require that the compiler have
access to both the caller and the callee, as a minimun, and possibly
all the code in between (if global analysis is to be used to determine
the run time types of objects). It follows that separate compilation
of C++ programs can (fundamentally) inhibit these optimizatins.


In conclusion,


Whether we like it or not, object-oriented programming and C++ are not
going away. These sort of optimizations are going to become more and
more important as C++ dominates C. While SPEC may not change so
quickly, the effective power of a machine/compiler combination is how
well it performs on the applications used, more and more of which will
be written in C++.


For background information see the work of the S{\sc elf} group
including the PhD thesis of Craig Chambers and that of Urs H\"{o}lzle.
and our own work on the Illinois Concert project:
                            http://www-csag.cs.uiuc.edu/


--------------------------
John Plevyak (plevyak@uiuc.edu) 2233 Digital Computer Lab, (217) 244-7116
                          Concurrent Systems Architecture Group
                          University of Illinois at Urbana-Champaign
                          1304 West Springfield
                          Urbana, IL 61801
<A HREF="http://www-csag.cs.uiuc.edu/individual/jplevyak">My Home Page</A>
--


Post a followup to this message

Return to the comp.compilers page.
Search the comp.compilers archives again.