[cpp-threads] RE: "Agenda" for august 23-25 concurrency meeting

Howard Hinnant hinnant at twcny.rr.com
Thu Aug 31 19:14:56 BST 2006


On Aug 31, 2006, at 1:28 PM, Nick Maclaren wrote:

>> Today's advice is to pass an empty vector to your function by
>> reference, out of fear that if you were to return it by value, RVO
>> will not kick in:
>>
>>      void compute(vector<int>& v, input data);  // guaranteed  
>> efficient
>>
>> vs:
>>
>>      vector<int> compute(input data);  // is this ridiculously
>> expensive?
>
> Well, it may be.  And so may the first be.  You are thinking heaps;
> if the implementor is thinking (Algol 68 style) stacks, you have just
> done precisely the wrong thing.

The rvalue reference proposals have no impact what-so-ever on stack- 
based objects (e.g. array<T,N>, complex<T>, etc.).

vector, used in this example, is mandated to be heap-owning.  That is  
not up to vendor discretion.  And there are no existing  
implementations of vector which do not store items on the heap.

There exists one std::container which sometimes stores data "on the  
stack": basic_string.  I have written an sso-based std::basic_string  
and I'm pleased to report that its performance is significantly  
enhanced, not degraded, by move semantics, including returning it by  
value from a function.  This is especially true in a multithreaded  
environment, and even more so as the number of cores increases (and  
the cost of synchronization with it).

>
>>            *** Move semantics enables guilt-free functional
>> programming. ***
>
> I am afraid not.  That is true only if the implementor is also  
> thinking
> the same way.

Sorry Nick, I have far more experience with move semantics in C++  
than you do, and a full implementation on my desk right now.  I have  
written most of the proposed wording.  There is no implementor wiggle  
room here as far as achieving guaranteed O(1) performance of  
traditionally heavy weight standard objects such as vector.  And the  
mechanisms for enabling this optimization in user-defined heavy  
weight (heap-owning) types are just drop-dead simple (simpler than  
writing a copy constructor and assignment operator).

      *** Move semantics enables guilt-free functional programming. ***

Sure, if you've got a std::array<int, 10000>, you might want to think  
twice before returning that guy by value.  For that matter, you might  
want to think twice about your design of passing such an object in  
and out of scopes in the first place.  Perhaps the client should have  
chosen std::vector<int>.

There is no reason that I can see to mandate that vector<int> (and  
all of the other containers) be inefficient to return from  
asynchronous functions.  They will be dirt cheap (0(1)) to return  
from synchronous functions (no vendor discretion needed).

> Now, the people who have most experience here are the Fortran  
> 90/95/2003
> brigade.  I am not fully in touch with the details, as most of the  
> real
> Fortran 90 programmers here needed little help with Fortran, and I  
> spent
> most time on Fortran 77 style code, libraries etc.  But their  
> experience
> is VERY relevant.

Fwiw, Fortran was my first language too (IV).

-Howard




More information about the cpp-threads mailing list