- Assigning to a literal - 3 Updates
- Assigning to a literal - 3 Updates
- n-ary roots from complex numbers... - 3 Updates
- A decent read/write mutex... - 1 Update
JiiPee <no@notvalid.com>: Apr 20 07:33PM +0100 On 20/04/2017 17:38, Stefan Ram wrote: > auto string =( "abc"s += "def" ); > ::std::cout << string << '\n'; interesting. good to know. Thanks. What is the purpose of s after abs? why it needs to be there? |
JiiPee <no@notvalid.com>: Apr 20 07:34PM +0100 On 20/04/2017 17:38, Stefan Ram wrote: > auto string =( "abc"s += "def" ); > ::std::cout << string << '\n'; > . or is it possibly that s creates a temorary string out of abc? |
Cholo Lennon <chololennon@hotmail.com>: Apr 20 03:52PM -0300 On 20/04/17 15:33, JiiPee wrote: >> ::std::cout << string << '\n'; > interesting. good to know. Thanks. > What is the purpose of s after abs? why it needs to be there? http://en.cppreference.com/w/cpp/string/basic_string/operator%22%22s -- Cholo Lennon Bs.As. ARG |
ram@zedat.fu-berlin.de (Stefan Ram): Apr 20 04:38PM I only now became aware of the fact that in C++ one now can /assign to a literal/: "abc"s = "def"s; . For another example, auto string =( "abc"s += "def" ); ::std::cout << string << '\n'; . |
ram@zedat.fu-berlin.de (Stefan Ram): Apr 20 06:35PM >or is it possibly that s creates a temorary string out of abc? Yes. The type of "abc"s is ::std::string . |
ram@zedat.fu-berlin.de (Stefan Ram): Apr 20 06:46PM >is >::std::string >. In C++17, that is. |
Alain Ketterlin <alain@universite-de-strasbourg.fr.invalid>: Apr 20 11:49AM +0200 Sorry I'm off-topic, but I can't resist... [...] > No, 57 is a prime number. [...] Sure, it's called the "Grothendieck prime". See https://en.wikipedia.org/wiki/57_(number) The fact that 57 = 19*3 is irrelevant here. -- Alain. |
David Brown <david.brown@hesbynett.no>: Apr 20 01:24PM +0200 On 20/04/17 01:09, Alf P. Steinbach wrote: >> On 19/04/17 13:20, Alf P. Steinbach wrote: >>> On 19-Apr-17 9:24 AM, David Brown wrote: >>>> On 19/04/17 01:58, Alf P. Steinbach wrote: <snip> > No, 57 is a prime number. That means the stabs fall all over the range > of the approximation. In different parabolas, yes, but they're all the > same kind. 57 is perhaps better than, say, 60. But it is still just stabs. It is just a test routine done on a PC - why not use more stabs? 92221 would be a nice number (it's prime too). > He he, teeny tiny. :) > Well it would be huge if most every function was outfitted with that > kind of supporting baggage. But `sin` is sort of fundamental. I once worked on a program where a new feature the customer wanted took a few hours to code - but it took a couple of days to free up the extra /bit/ of data space needed. (It was not written in C++ :-) ) >> Surely you could generate this table directly at compile time, with >> constexpr functions? > No, sorry. First of all the standard library's `sin` isn't `constexpr`. You could write a slow but accurate constexpr sin, using the Taylor series. > And secondly, the usual way to generate a table at compile time is to > use `std::index_sequence`, a type templated by the index values, and I > guess one would run into an implementation limit long before 10 000. Yes, you need to be more clever than that. I remember reading somewhere that you cannot initialise a constexpr std::array using a loop, but it is possible to do with something that looks mostly like a std:array. I have, unfortunately, forgotten the details - maybe I will try to figure it out when I get the time. If you want to use template metaprogramming for something like this, you have to build up using binary trees of templates, rather than a simple head++tail list, so that your depth here will be 13 rather than 10000. >> calculations (but only storing double precision in the table). > Yeah, maybe. But I think errors with `double` here would be in the last > digit only. Yes - but if you can avoid the error easily, why not do so? >> A 16 entry table was sufficient for 21 bits of accuracy - fine for >> single precision maths. > Oh, that's pretty smart. :) Yes, it was fun. The result was the customer's critical control loop running in less than 1% of the time it originally took - they were rather pleased with that. I made another version that used larger tables, combined with a series of complicated DMA setups triggered by hardware timers that worked even faster, and generated sine waves on an analogue output even while the processor was stopped. Once I got down to 0% processor usage, it was time to deliver the software. |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Apr 20 02:21PM +0200 On 20-Apr-17 11:49 AM, Alain Ketterlin wrote: > https://en.wikipedia.org/wiki/57_(number) > The fact that 57 = 19*3 is irrelevant here. > -- Alain. Lols. :) It spreads nicely anyway. Sorry about that gaffe. Cheers!, - Alf |
"Chris M. Thomasson" <invalid@invalid.invalid>: Apr 19 04:28PM -0700 On 4/15/2017 10:47 PM, Chris M. Thomasson wrote: > If you read all of the data in the links, one can implement it for > themselves. Is there any interest in my upcoming pure c++ std impl of > this rw-mutex? Thanks. One the path to raw C++ that compiles with normal systems. This is a Relacy test unit! Working wrt my decent rw-mutex, well, sometimes these exotic atomic and membars can be used to implement your favorite sync primitive! C++ Relacy Test Unit _______________________________ // Unbounded Wait-Free Reader Writer Mutex // by Chris M. Thomasson Experiment // In relacy at: // http://www.1024cores.net/home/relacy-race-detector #include <relacy/relacy_std.hpp> #include <cstdio> #include <climits> #define mb_relaxed std::memory_order_relaxed #define mb_consume std::memory_order_consume #define mb_acquire std::memory_order_acquire #define mb_release std::memory_order_release #define mb_acq_rel std::memory_order_acq_rel #define mb_seq_cst std::memory_order_seq_cst #define mb_fence(mb) std::atomic_thread_fence(mb) struct cpp_sem { VAR_T(int) m_count; std::mutex m_mutex; std::condition_variable m_cond; cpp_sem(int count = 0) : m_count(count) { RL_ASSERT(count > -1); } void sub(int c) { RL_ASSERT(c > 0); m_mutex.lock($); while (VAR(m_count) < c) m_cond.wait(m_mutex, $); VAR(m_count) -= c; m_mutex.unlock($); } void add(int c) { RL_ASSERT(c > 0); m_mutex.lock($); VAR(m_count) += c; m_mutex.unlock($); if (c < 2) { m_cond.notify_one($); } else { m_cond.notify_all($); } } }; struct ct_rw_mutex { std::atomic<long> m_count; std::atomic<long> m_rdwake; std::atomic<long> m_wrlockset_state; cpp_sem m_wrlockset; cpp_sem m_wrwset; cpp_sem m_rdwset; ct_rw_mutex() : m_count(INT_MAX), m_rdwake(0), m_wrlockset_state(1), m_wrwset(0), m_rdwset(0) { } ~ct_rw_mutex() { RL_ASSERT(m_count.load(mb_relaxed) == INT_MAX); RL_ASSERT(m_rdwake.load(mb_relaxed) == 0); } void wrlock() { if (m_wrlockset_state.fetch_sub(1, mb_relaxed) < 1) { m_wrlockset.sub(1); } mb_fence(mb_acquire); int count = m_count.fetch_add(-INT_MAX, mb_relaxed); if (count < INT_MAX) { if (m_rdwake.fetch_add(INT_MAX - count, mb_relaxed) + INT_MAX - count) { m_wrwset.sub(1); } } mb_fence(mb_seq_cst); } void wrunlock() { mb_fence(mb_release); int count = m_count.fetch_add(INT_MAX, mb_relaxed); if (m_wrlockset_state.fetch_add(1, mb_relaxed) < 0) { m_wrlockset.add(1); } // Release Readers after mutex unlock, // Totally Experimental, works in Relacy! ;^) if (count < 0) { m_rdwset.add(-count); } } void rdlock() { int count = m_count.fetch_sub(1, mb_relaxed); if (count < 1) { m_rdwset.sub(1); } mb_fence(mb_acquire); } void rdunlock() { mb_fence(mb_release); int count = m_count.fetch_add(1, mb_relaxed); if (count < 0) { mb_fence(mb_seq_cst); if (m_rdwake.fetch_sub(1, mb_relaxed) == 1) { m_wrwset.add(1); } } } }; // Single producer consumer spin queue #define PRODUCERS 3 #define CONSUMERS 3 #define READERS 4 #define THREADS (PRODUCERS + CONSUMERS + READERS) #define N 3 #define START 4 static_assert( PRODUCERS == CONSUMERS && N > 0, "This test wants the number of producers" "and consumers to be equal:" "Also, N needs to be greater than zero; damn it!" ); struct ct_rw_mutex_test : rl::test_suite<ct_rw_mutex_test, THREADS> { ct_rw_mutex g_rw_mutex; VAR_T(int) g_shared; ct_rw_mutex_test() : g_shared(START) {} void after() { RL_ASSERT(VAR(g_shared) == START); } void thread_producer(unsigned int tidx) { //std::printf("thread_producer::%u\n", tidx); for (unsigned int i = 0; i < N; ++i) { g_rw_mutex.wrlock(); ++VAR(g_shared); g_rw_mutex.wrunlock(); } } void thread_consumer(unsigned int tidx) { //std::printf("thread_consumer::%u\n", tidx); for (unsigned int i = 0; i < N; ++i) { g_rw_mutex.wrlock(); --VAR(g_shared); g_rw_mutex.wrunlock(); } } void thread_reader(unsigned int tidx) { //std::printf("thread_reader::%u\n", tidx); for (unsigned int i = 0; i < N; ++i) { g_rw_mutex.rdlock(); int shared = VAR(g_shared); g_rw_mutex.rdunlock(); // double check our read range! RL_ASSERT( shared > (-CONSUMERS * N + START) && shared < (PRODUCERS * N + START) ); } } void thread(unsigned int tidx) { if (tidx < PRODUCERS) { thread_producer(tidx); } else if (tidx < PRODUCERS + CONSUMERS) { thread_consumer(tidx); } else { thread_reader(tidx); } } }; int main() { { rl::test_params p; p.iteration_count = 14000; // for existing proxy gc code p.execution_depth_limit = 33333; p.search_type = rl::random_scheduler_type; //p.search_type = rl::sched_bound; //p.search_type = rl::fair_full_search_scheduler_type; //p.search_type = rl::fair_context_bound_scheduler_type; rl::simulate<ct_rw_mutex_test>(p); } std::puts("\nTest Complete!\n"); std::getchar(); return 0; } _______________________________ Will have normal std c++ in a day or two. Posted here, for all of the wonderful contributors and readers of this fine group. |
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page. To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com. |
No comments:
Post a Comment