On 7 Jan 2014 at 13:21, Oliver Kowalke wrote:
My only qualm with the design really is I wish there were combined fibre/thread primitives i.e. say a future implementation which copes with both fibers and threads.
my intention was that another library combines fibers and threads (some kind of thread-pool with worker-threads using fibers).
Oh great! If you had a Design Rationale page which specifically says such a feature is out of scope for Boost.Fiber because it's a more complex additional layer which happens to be provided in another library X (preferably with link to it), then I would be very pleased.
My only issue is that the Boost.Thread mirror classes do not fully mirror those in Boost.Thread.
Because I decided that the interface of std::thread should be the blue-print. Boost.thread has (at least for my taste) too many extensions/conditional compilations etc.
Well ... I agree that thread cancellation support is probably a step too far, but I think there is also a reasonable happy medium between C++11 and Boost.Thread. Put it another way: what out of Boost.Thread's additions would look extremely likely to appear to C++17? The future::get_exception_ptr() is a very good example, it saves a lot of overhead when you're transferring exception state from one future to another.
1. There is no formal reference section. What bits of reference section there is does not contain reference documentation for all the useful classes (e.g. the ASIO support).
OK - I followed the style of other boost libraries (like boost.thread) - it seams there is no 'standard' regarding to this topic.
I do think you need reference docs for the ASIO support classes. I don't understand what they do, and I think I ought to.
2. I see no real world benchmarks. How are people supposed to know if adopting fibers is worthwhile without some real world benchmarks? I particularly want to know about time and space scalability as the number of execution contexts rises to 10,000 and beyond.
boost.fiber uses boost.coroutine (which itself uses boost.context) and provides some performance tests for context switching.
Sure. But it's a "why should I use this library?" sort of thing? If I see real world benchmarks for a library, it tells me the author has probably done some performance tuning. That's a big tick for me in considering to use a library. It also suggests to me if refactoring my code is worth it. If Boost.Fiber provides only a 10x linear scaling improvement, that's very different from a log(N) scaling improvement. A graph making it very obvious what the win is on both CPU time and memory footprint makes decision making regarding Fiber support much easier. Put it another way: if I am asking my management for time to prototype adopting Fibers in the company's core software, a scaling graph makes me getting that time a cinch. Without that graph, I have to either make my own graph in my spare time, or hope that management understands the difference between fibers and threads (unlikely).
Of course I could provide a benchmark for a simple task running a certain amount of fibers - but what would be a good example for such a task?
You don't need much: a throughput test of null operations (i.e. a pure test of context switching) for total threads 1...100,000 on some reasonably specified 64 bit CPU e.g. an Intel Core 2 Quad or better. I generally would display in CPU cycles to eliminate clock speed differences. Extra bonus points for the same thing on some ARMv7 CPU.
3. I see no listing of compatible architectures, compilers, etc. I want to see a list of test targets, ones regularly verified as definitely working. I also want to see a list of minimum necessary compiler versions.
boost.fiber itself contains simple C++03 code - the only restriction to architectures is defined by boost.context (because it's using assembler).
Eh, well then I guess you need a link to the correct page in boost.context where it lists the architectures it works on. Certainly a big question for anyone considering Fiber is surely "will it work on my CPU"?
4. I deeply dislike the documentation simply stating "Synchronization between a fiber running on one thread and a fiber running on a different thread is an advanced topic.". No it is not advanced, it's *exactly* what I need to do. So tell me a great deal more about it!
because fibers do not use the underlying frameworks (like pthread) used by boost.thread. usually you run dependend fibers in the same thread concurrently. if your code requires that a fiber in thread A waits on a fiber running in thread B it is supported by boost.fiber using atomics (sync. primitves use atomics internally).
Sure, but I definitely won't be using Fibers that way. And I saw Antony had the same observation too. I think you need some more docs on this: just tell us what is possible, what works and how it works and we'll figure out the rest. I definitely need the ability to signal a fibre future belonging to thread A from some arbitrary thread B. I'll also need to boost::asio::io_service::post() to an ASIO io_service running fibers in thread A from some arbitrary thread B.
5. Can I transport fibers across schedulers/threads? swap() suggests I might be able to, but isn't clear. If not, why not?
not swap() - you have to move the fiber from fiber-scheduler scheduling fibers in thread A to fiber-scheduler ruinning in thread B. for this purpose boost.fiber proivides the class round_robin_ws which has member-functions steal_from() and migrate_to() to move a fiber between threads.
That's great news, I'll be needing that too.
6. What is the thread safety of fiber threading primitives? e.g. if a fibre waits on a fibre future on thread A, can thread B signal that fibre future safely?
it's supported
The docs need to explicitly say so then, and indeed thread safety for *every* API in the library. Complexity guarantees and exception safety statements for each API would also be nice. I know they're a real pain to do, but it hugely helps getting the library into a C++ standard later.
7. I want to see worked tutorial examples in the documentation e.g. step me through implementing a fibre pool, and then show me how to implement a M:N threading solution. That sort of thing, because this is another majority use case.
this an advanced topic and should not be part of this lib. I'm working currently on a library implementing a thread-pool which uses internally fibers. It maps to a M:N solution. boost.fiber itself should provide only the low-level functionality (same as boost.context does for boost.coroutine and boost.coroutine acts for boost.fiber). the lib contains a unit-tests (test_migration) which shows how a fiber can be migrated between two threads (this code shows how work-stealing/work-sharing can be implemented in a thread-pool).
If you have a section in a design rationale page saying this, I would be happy.
8. There are quite a few useful code examples in the distribution in the examples directory not mentioned in the formal docs (which is bad, because people don't realise they are there), but they don't explain to me why and how they work. I find the ASIO examples particularly confusing, and I don't understand without delving into the implementation code why they work which is a documentation failure. This is bad, and it needs fixing.
I've added comments to the publisher-subscriber example. Does the comments in the code explain the ideas better?
I'll get back to you on your comments later. I think, as a minimum, all the examples need to appear verbatim in the docs (quickbook makes this exceptionally easy, in fact it's almost trivial). This is because Boost docs tend to appear on Google searches far quicker than code in some git repo. Niall -- Currently unemployed and looking for work. Work Portfolio: http://careers.stackoverflow.com/nialldouglas/