Very briefly, some of us are interested in having a standardized function which does not incur an upfront memory allocation to store the callable target, instead opting for a compile time specified buffer (stack allocated).
I don't think you mean stack allocated; I think you mean the space is embedded in the object (aka the small object optimization). If the object is allocated on the heap, the space will also be in the heap, correct?
Hi Carl
Can you explain somewhere why std::function is unable to do that?
In other words, why must std::function allocate memory?
> Very briefly, some of us are interested in having a standardized
> function which does not incur an upfront memory allocation to store
> the callable target, instead opting for a compile time specified
> buffer (stack allocated). This has been quite useful in several low
> latency domains such as gaming and electronic trading. In other words,
> a drop-in replacement for std::function, where all data is on the
> stack.
Isn't this already possible by using today's `std::function` with a
custom allocator backed by a stack-based array?
std::function<void()> a_func()
{
return []{};
}
std::inplace_function<int(), VALUE> func()
{
return [x = 12]() {return x;};
}
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposal...@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/e00db911-40f5-4c11-a4b8-32bba77aa0a5%40isocpp.org.
Hi all,
Thanks very much for the feedback so far, this is exactly what I was looking for.Below are my responses to the questions raised. Please let me know if I haven't answered concisely enough, or have misunderstood the comments.
- Is this too specialized for the standard library? Should this be in a TR/boost/extension only?
- This is the most important comment in my opinion, and the driver for this proposal - to determine the level of support
- Possibly it should be kept out of the standard. Here we are talking about introducting a whole new type, plus optionally specifying buffer sizes/alignment, just to save an allocation
- On the flip side, it's actually more than an allocation. It's cache locality, potential to prefetch, deterministic performance, etc
- This leads on to a bigger question - should low latency/high performance be a concern of the standard library?
- I would argue yes, as industries such as finance/games/image processing/aerospace represent a large set of C++ users, and low latency requirements are a reality
- How to determine the correct buffer size, at all times?
- You can't. For that, fall back to std::function
- In reality, inplace_function will only be used in specialized cases, and for that you will have a good idea of the size of the callable object
- If your size is too conservative, the static assert will tell you what size you should have used
- Also, from experience, the implementation's default size is fine 90% of the time
- Why not consider a custom allocator?
- Primarily, for performance (keeping the allocated memory together with the function object itself is important, for example)
- A secondary concern is simplicity (another template argument introduces more complexity in terms of copy construction, assignment, etc)
- That was a good point about the allocator memory outliving the function as well
- Another concern is giving the implementation freedom in terms of memory layout/alignment/type erasure/management function pointers, etc (custom allocators make this harder to acheive)
- I'll add this discussion to the design considerations part of the spec
- What's the difference between inplace_function and LLVM's function_ref?
- Excellent point - I've not seen function_ref until today
- One difference - an inplace_function can be stored/copied/moved, even for non-trivial callable objects (for function_ref you'd need a second step of converting this to a std::function before storing/copying)
- Another difference - I am not convinced function_ref successfully captures closures correctly (at least in GCC on -O1 or above, it doesn't appear to capture out of scope variables by reference or copy)
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/ff1087cf-5777-47e9-8caa-d28136aae130%40isocpp.org.
Hi all,Thanks very much for the feedback so far, this is exactly what I was looking for.Below are my responses to the questions raised. Please let me know if I haven't answered concisely enough, or have misunderstood the comments.
- Is this too specialized for the standard library? Should this be in a TR/boost/extension only?
- This is the most important comment in my opinion, and the driver for this proposal - to determine the level of support
- Possibly it should be kept out of the standard. Here we are talking about introducting a whole new type, plus optionally specifying buffer sizes/alignment, just to save an allocation
- On the flip side, it's actually more than an allocation. It's cache locality, potential to prefetch, deterministic performance, etc
- This leads on to a bigger question - should low latency/high performance be a concern of the standard library?
- I would argue yes, as industries such as finance/games/image processing/aerospace represent a large set of C++ users, and low latency requirements are a reality
- How to determine the correct buffer size, at all times?
- You can't. For that, fall back to std::function
inplace_function<...> f(a_functor);
std::function<...> g = f;
std::function<...> g(a_functor);
Please keep in mind that the primary goal of this proposal (at present) is to measure the interest/response of such a mechanism. But I do note several related proposals such as small/inplace vectors, inplace strings, inplace any/variant - i.e. there seems to be a theme here.
On Thu, Jul 14, 2016 at 3:56 PM, Carl Cook <carl...@gmail.com> wrote:
- What's the difference between inplace_function and LLVM's function_ref?
- Excellent point - I've not seen function_ref until today
- One difference - an inplace_function can be stored/copied/moved, even for non-trivial callable objects (for function_ref you'd need a second step of converting this to a std::function before storing/copying)
- Another difference - I am not convinced function_ref successfully captures closures correctly (at least in GCC on -O1 or above, it doesn't appear to capture out of scope variables by reference or copy)
llvm::function_ref doesn't capture anything, and is not supposed to -- it's a *non-owning* handle to a callable that outlives the handle. (llvm::function_ref is to std::function as std::string_view is to std::string.) This is a feature and a design goal of llvm::function_ref, but I think it means it's addressing a fundamentally different problem than the one you're tackling here (which seems to be essentially, "let me control the size and alignment in std::function's small function optimization")
It's not a question of "should the standard library care about high-performance code". It's a question of "how many high-performance corner cases should be in the standard library?" You can keep adding stuff to cover corner cases ad infinitum. At some point, you have to draw a line.
Remember: we are talking about a type which, in the very next section, you admit "will only be used in specialized cases". To me, the standard library should be for tools that are of general use.
That's why I like the idea of having a dedicated TS specifically for these types of things. I'd love to see a TS full of `small_vector`, `small_basic_string`, `inplace_function`, and so forth (but not `flat_set/map`. Those need to be in the standard library). Please don't look on TS's as some kind of ghetto for things that are not really standard. Yes, they really are standard, they really are supplied by compiler vendors, and they really are available.
This actually brings up a small technical deficiency with the current proposal: no interop with `std::function`. Well, besides the obvious fact that `inplace_function` is a callable and you could therefore shove one into a `function` and vice-versa.
It's not a question of "should the standard library care about high-performance code". It's a question of "how many high-performance corner cases should be in the standard library?" You can keep adding stuff to cover corner cases ad infinitum. At some point, you have to draw a line.
This actually brings up a small technical deficiency with the current proposal: no interop with `std::function`. Well, besides the obvious fact that `inplace_function` is a callable and you could therefore shove one into a `function` and vice-versa.
We ought to be able to convert between the two without creating overhead.
On 14 July 2016 at 21:57, Nicol Bolas <jmck...@gmail.com> wrote:
It's not a question of "should the standard library care about high-performance code". It's a question of "how many high-performance corner cases should be in the standard library?" You can keep adding stuff to cover corner cases ad infinitum. At some point, you have to draw a line.
Why?I remember back in '12 when the big complaint was that the C++ Standard Library was too small. I must have been sleeping when that got solved.
My personal criterion are:
- Things that people keep inventing in multiple places
- Things that are hard to write correctly
Remember: we are talking about a type which, in the very next section, you admit "will only be used in specialized cases". To me, the standard library should be for tools that are of general use.
That's you. And no one is forcing you to use the other stuff.
That's why I like the idea of having a dedicated TS specifically for these types of things. I'd love to see a TS full of `small_vector`, `small_basic_string`, `inplace_function`, and so forth (but not `flat_set/map`. Those need to be in the standard library). Please don't look on TS's as some kind of ghetto for things that are not really standard. Yes, they really are standard, they really are supplied by compiler vendors, and they really are available.
And people who work on them expect the stuff in them to go into the IS at some point.
If you wish to change the focus of TSes, you need to come to meetings and present your case.
This actually brings up a small technical deficiency with the current proposal: no interop with `std::function`. Well, besides the obvious fact that `inplace_function` is a callable and you could therefore shove one into a `function` and vice-versa.
Why? What are the actual use cases for that?
The use case of "someone used `std::function` in an interface, but I use `std::inplace_function` internally, and I need to talk to their code." Right now, `std::function` is how lots of C++ code takes callbacks, and for good reason. But if I've wrapped some function in an `inplace_function`, I still need to be able to talk to them.
llvm::function_ref doesn't capture anything, and is not supposed to -- it's a *non-owning* handle to a callable that outlives the handle. (llvm::function_ref is to std::function as std::string_view is to std::string.) This is a feature and a design goal of llvm::function_ref, but I think it means it's addressing a fundamentally different problem than the one you're tackling here (which seems to be essentially, "let me control the size and alignment in std::function's small function optimization"
int non_const_var = 0xf;function_ref<int()> f_ref = [&]() { return non_const_var;};return f_ref();
The allocator support in std::function has been zapped as of three weeks ago.
From: Carl Cook Sent: Sunday, July 31, 2016 8:10 AM To: ISO C++ Standard - Future Proposals Reply To: std-pr...@isocpp.org Subject: Re: [std-proposals] Proposal - non allocating std::function |
The allocator support in std::function has been zapped as of three weeks ago.
function_ref<int()> f_ref = [&]() { return non_const_var;};
Understood, thanks. Hence llvm::function_ref really is what it says. I.e. don't use it beyond references to functions.
--
You received this message because you are subscribed to a topic in the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this topic, visit https://groups.google.com/a/isocpp.org/d/topic/std-proposals/vven2Om7Ha8/unsubscribe.
To unsubscribe from this group and all its topics, send an email to std-proposal...@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/ee95d8af-e8e9-47bc-9d61-d95551aac4f3%40isocpp.org.