- Request Feedback on Test - 8 Updates
- CRTP and overhead - 3 Updates
- Why uniform_int_distribution does no produce all values? - 1 Update
- Go to church - 3 Updates
- [ot] set sound on frame - 3 Updates
- collection of pointers vs collection of objects - 1 Update
- Serializing variant objects - 2 Updates
- Finding CPU utilization of NUMA nodes - 2 Updates
- The required minimum omega for double - 1 Update
Tim Rentsch <txr@alumni.caltech.edu>: Feb 12 08:22AM -0800 >> dictionary. > Oh! > [..program..] I'm enjoying your algorithms (although I must admit I find the layout style visually jarring). If you're taking votes, count mine to continue as you have been. What would you do if the input were not guaranteed to be sorted? (And a side question: when will we see the next installment of thread AVL tree tutorial?) |
scott@slp53.sl.home (Scott Lurndal): Feb 10 09:13PM >the dictionary still, at least until a letter is rejected along the >path. So, while compact, this is not necessarily going to perform any >better, right? The algorithm first scans the matrix for the first character of the test string[*]. If not found, go to the next string. So worst case, we look at each element in the matrix once. Best case, we look at one single matrix entry to start the word. If the first character of the test string is in the matrix, then we check each of the 8 surrounding characters for a match against the second character, and bail if not found. If found, recurse. We never allocate or deallocate memory (which your algorithms do). The algorithm needs a small update to not visit the same matrix location twice for a given word while recursing. With a matrix this small, the entire thing fits into the processor cache, with a larger matrix, the prefetcher would kick in. It would be require a bit more space to handle multibyte UTF-8, UTF-16 or UTF-32 glyph data. [*] A really good compiler would generate a SCASB instruction for this on intel systems. |
scott@slp53.sl.home (Scott Lurndal): Feb 10 09:15PM >the dictionary still, at least until a letter is rejected along the >path. So, while compact, this is not necessarily going to perform any >better, right? The "trick" here (which I learned back in 1979) is to put a fence around the matrix so the algorithm doesn't have to special case cells at the borders. |
"Christopher J. Pisz" <cpisz@austin.rr.com>: Feb 10 07:14PM -0600 On 2/10/2017 1:43 AM, Christopher J. Pisz wrote: > Eurika! > I am implementing this now. I suspect it will greatly speed things up. Pushed algorithm 2 to github. It is significantly worse. |
Tim Rentsch <txr@alumni.caltech.edu>: Feb 12 08:51AM -0800 > C++ is getting REALLY performance orientated. I used to get a job > within 2 days just by knowing what virtual inheritance is. Now, I > don't really know how to "Get better" I have some comments about the problem and then some comments about the job search/interview area. I didn't look closely at your program. The problem is kind of strange, or maybe I should say surprising. Usually for this kind of "puzzle" program, the dictionary would be fixed, and then we would want to solve lots of different board positions. In that scenario time taken to process the dictionary is normally deemed negligible (within reason, of course), because what is important to optimize is the time to solve a board. Here the situation is the opposite of that. We have _one_ small board, and a potentially unbounded dictionary. The program needs to do something with each dictionary word, even if just to read and discard it. So for this problem the emphasis should be on doing as little work as possible for each input word. It isn't obvious how to do that. I took a run at writing a program for this, and it took me couple of false starts before I got one whose performance is competitive. I guess I should give a hint huh? Okay my hint is this: there is a lot of information in the board state, which is small; pre-process the board state to allow an algorithm that can skip a candidate word very quickly, which will be true for most words. For now I think I'll leave it at that, but feel free to ask if you want a further hint (or hints). About interviewing: especially when you run into a problem like this one, but also more generally, design decisions can depend a lot on the details of the problem. Ask about those: make sure you know what the boundaries are for what the program has to do, and also how the result will be judged. Of course, try to ask smart questions more than dumb questions, but ask. Just the act of asking should raise their estimation of you, and if there is some insight to the questions that will be even better. And, not to be neglected, the answers may help you write a better program, and write it more quickly. (I hope the above isn't too preachy or obvious. I wanted to say it because your comments make me think you're focusing on finding a solution more than on improving the process of how you look for solutions. It's important not to neglect the process aspect.) |
Tim Rentsch <txr@alumni.caltech.edu>: Feb 12 09:05AM -0800 > walking through the entire dictionary and testing iteratively whether > each word in the dictionary is on the board. On a large dictionary > that is about the worst possible implementation. [...] It might seem that way but actually it is not so. I wrote a program for this problem, roughly like this pseudo-code: read board file prepare search structures based on board file for each word in dictionary file if is-on-board( word ) print word endif endfor The performance is pretty good, a little bit faster than Alf's code. (I should add that this comparison may be a bit unfair since my program was written in C rather than C++.) |
"Öö Tiib" <ootiib@hot.ee>: Feb 12 12:25PM -0800 On Sunday, 12 February 2017 19:05:19 UTC+2, Tim Rentsch wrote: > The performance is pretty good, a little bit faster than Alf's > code. (I should add that this comparison may be a bit unfair > since my program was written in C rather than C++.) Why comparing performance of C program with C++ program may be is bit unfair? |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Feb 13 12:21AM +0100 On 11.02.2017 13:52, Chris Vine wrote: >> substring of other, instead of just comparing lengths then. >> Even for a first working version that was, well, dumb. :) > I think your code was OK on the equality test. Well, slower than necessary. :o) > to me that since 'lower' could be at 'end_dict_range', this should > probably be checked for before 'lower' is dereferenced on calling > starts_with().) Good point, I didn't think of that. That's a bug. Another bug is that I intended to use a matrix with border but as I can see it was dimensioned as (n + 1)×(n + 1) instead of (n + 2)×(n + 2). Ugh. I can believe I did that, but then, I just cobbled something up. I wonder if Andrey Karpov's static checked (PVS studio) could have any chance of detecting these bugs? For the non-dereferencable iterator, instead of extra checking one can theoretically add a dummy zero-length word, a sentinel value, at the end of the dictionary and pass iterator to that, instead of beyond, as end-iterator. But that to some degree breaks the structure of the design, e.g. the same code can't be handed a dictionary that is without such a sentinel value, and trying it out I found that it also made for more complicated `assert`s about the data. So, an extra check it is. With the bugs fixed the code, minus the Matrix class definition and the file reading & checking, now looks like this in ¹Expressive C++: inline $function starts_with( ref_<const string> prefix, ref_<const string> s ) -> bool { $let prefix_length = length_of( prefix ); if( prefix_length > length_of( s ) ) { return false; } return s.compare( 0, prefix_length, prefix ) == 0; } using Dictionary_iter = vector<string>::const_iterator; struct Position { Index x; Index y; }; $procedure recursively_append_words_from( const Dictionary_iter start_dict_range, const Dictionary_iter end_dict_range, ref_<const Matrix<char>> board, const Position position, ref_<Matrix<bool>> visited, ref_<string> word, ref_<vector<string>> result ) { $let original_word_length = word.length(); $let ch = board.item( position.x, position.y ); if( ch == 'q' ) { word += "qu"; } else { word += ch; } $let it_dict_entry = lower_bound( start_dict_range, end_dict_range, word ); if( it_dict_entry != end_dict_range and starts_with( word, *it_dict_entry ) ) { $let length = word.length(); if( length >= 3 and length == it_dict_entry->length() ) { result.push_back( word ); } visited.item( position.x, position.y ) = true; for( $each dy $in range( -1, +1 ) ) for( $each dx $in range( -1, +1 ) ) { Position const new_position = {position.x + dx, position.y + dy}; if( not visited.item( new_position.x, new_position.y ) ) { recursively_append_words_from( it_dict_entry, end_dict_range, board, new_position, visited, word, result ); } } visited.item( position.x, position.y ) = false; } word.resize( original_word_length ); } $procedure append_words_from( ref_<const vector<string>> dictionary, ref_<const Matrix<char>> board, ref_<const Position> start, ref_<vector<string>> result ) { string word; $let board_size = board.size(); Matrix<bool> visited{ board_size }; for( $each i $in i_up_to( board_size ) ) { visited.item( i, 0 ) = true; visited.item( 0, i ) = true; visited.item( i, board_size - 1 ) = true; visited.item( board_size - 1, i ) = true; } recursively_append_words_from( begin( dictionary ), end( dictionary ) - 1, board, start, visited, word, result ); } $procedure cpp_main( ref_<const vector<string>> args ) { // Using non-macro pure C++ `fail` to get unadorned message in exception: $hopefully( n_items_in( args ) == 3 ) or fail( ""s << "Usage: " << args[0] << " DICTIONARY BUBBLEBOARD" ); vector<string> const dictionary = load_dictionary( args[1] ); Matrix<char> const board = load_bubble_board( args[2] ); assert( is_sorted( $items_of( dictionary ) ) ); $let board_size = board.size(); $let n = board_size - 2; assert( n > 0 ); vector<string> words; for( $each y $in i_up_to( n ) ) for( $each x $in i_up_to( n ) ) { append_words_from( dictionary, board, {x + 1, y + 1}, words ); } sort( $items_of( words ) ); $let start_of_duplicates = unique( $items_of( words ) ); words.erase( start_of_duplicates, end( words ) ); for( $each word $in words ) { cout << word << "\n"; } } Cheers!, - Alf Notes: ¹ It's a little language extension library I couldn't resist creating after the "Fun with macros" posting here in clc++. The macros, supported by various templates, currently are defined as follows: # define $e ::progrock::expressive # # define $static_assert EXPRESSIVE_STATIC_ASSERT // Single arg like C++17. # define $funcname EXPRESSIVE_FUNCNAME // Qualified __func__. # define $noreturn EXPRESSIVE_NORETURN // MSVC lacks [noreturn]. # # define $function auto # define $procedure void # # define $simple_pure_function constexpr $function # define $compile_time_value static constexpr # # define $an_expected( Type, expr ) \ ( \ [&]{ $static_assert(( ::std::is_same<Type, decltype((expr))>::value )); }, \ expr \ ) # define $as static_cast # define $let auto const # define $let_mutable auto # define $name auto& # define $readonly_name auto const& # # // Range-based `for`, because deduced `auto`can't be expressed via e.g. `ref_`: # define $each_value auto const # define $each_ref auto& # define $each auto const& # define $in : # # define $repeat do{ # define $until(e) }while(not(e)) # # define $when( condition ) condition? # define $use( value ) value : # define $default_to( value ) value # # define $_generate_using_declaration_in( ns, name ) using ns::name; # define $using_from_namespace( ns, ... ) \ MM_APPLY_WITH_FIXED_ARG( $_generate_using_declaration_in, ns, __VA_ARGS__ ) \ static_assert( true, "- just to support a semicolon after this -" ) # # define $using_all_from_namespace( ns ) \ using namespace ns # # define $using_nested_namespace( ns, nested ) \ namespace nested = ns::nested # # define $lambda_using( ... ) [__VA_ARGS__] # define $byref( object ) &object # define $byval( object ) object # define $capture_byref & # define $capture_byval = # # define $lambda $lambda_using() # define $lambda_using_references $lambda_using( $capture_byref ) # define $lambda_using_values $lambda_using( $capture_byval ) # # define $hopefully( e ) $e::hopefully( e ) # define $fail( ... ) $e::fail_from_location( \ $as<std::string>( $funcname ), __VA_ARGS__ \ ) # # // Can't use unqualified type builders here, hence the `$e` qualifiers. # // The `(void)` casts avoids unused-warnings when these names are unused. # // Commonly `n_args` is named the more cryptic `argc` (with `c` for `count`), # // and commonly `args` is named the more cryptic `argv` (`v` for `values`). # // To use `n_args` and `args` you can pass a lambda as macro argument. # // The macro is variadic to allow specification of a fatal error handler. # define $start_with( ... ) \ $function main( const int n_args, $e::raw_array_<$e::ptr_<char>> args ) \ -> int \ { \ (void) n_args; (void) args; \ return $e::default_startup( __VA_ARGS__ ); \ } # # // This is just an extra-convenience wrapper and doesn't support a fatal # // error handler (modern C++ requires at least one argument for a `...`). # define $start_with_arguments( main_procedure ) \ $start_with( $lambda_using_values() \ { \ main_procedure( {args, args + n_args} ); \ } ) |
bitrex <bitrex@de.lete.earthlink.net>: Feb 12 02:24PM -0500 On 02/05/2017 11:30 AM, Alf P. Steinbach wrote: > one realizes that that's how the compiler deals with things here. > Cheers & hth., > - Alf Thanks for your helpful reply - sorry for my delay in getting back. A followup question: is there a better way to implement the CRTP when you want to inject a static data structure into a derived class, so the end result is that you get a new static structure for each variety of template of the derived class you instantiate? Like so: #include <array> #include <iostream> template <template <typename> class Derived, typename T> struct Foo { static std::array<T, 5>& my_array() { static auto my_array = std::array<T, 5>(); return my_array; } std::array<T, 5>& get() { return static_cast<Derived<T>*>(this)->get_impl(); } }; template <typename T> struct Bar : public Foo<Bar, T> { std::array<T, 5>& get_impl() { return this->my_array(); } }; int main() { auto baz = new Bar<int>(); auto bif = new Bar<short>(); baz->get() = {1, 2, 3, 4, 5}; bif->get() = {6, 7, 8, 9, 10}; for (auto i : baz->get()) { std::cout << i << std::endl; } for (auto c : bif->get()) { std::cout << c << std::endl; } return 0; } This works fine if you simply want to "inject" a single base class template into the derived class, but gets real messy real quick if you want to do a longer chain, or use multiple inheritance. Didn't know if there's some way to automate it more cleanly... |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Feb 12 10:26PM +0100 On 12.02.2017 20:24, bitrex wrote: > template into the derived class, but gets real messy real quick if you > want to do a longer chain, or use multiple inheritance. Didn't know if > there's some way to automate it more cleanly... Not sure exactly what you're asking but in the example the base class provides a member function `get` that calls derived class `get_impl` that accesses the base class' static array. That seems rather roundabout unless you intend `get_impl` as a kind of customization hook. And with `get_impl` doing something else, some customization, you will have needlessly outfitted the derived class with a static array. I think the easiest way to have an easily customizable static array in each most derived class, is to declare it there. But I may be way off, because I don't understand the purpose here. Cheers!, - Alf |
bitrex <bitrex@de.lete.earthlink.net>: Feb 12 05:18PM -0500 On 02/12/2017 04:26 PM, Alf P. Steinbach wrote: > But I may be way off, because I don't understand the purpose here. > Cheers!, > - Alf Sure, that code was just a boilerplate example. The situation I had in mind was where the static member in the inherited base class defines some more complicated resource-holding structure, like an allocator or policy, that's then injected into the derived class. On little processors like some of the ARM Cortex series it's often nice to have everything allocated statically at startup, and I was thinking with the CRTP I could make a base class that defines some common type of resource, and then use this type of "static polymorphism" so each derived class template type gets its own (all with static storage duration) copy of whatever that resource is to play with. |
JiiPee <no@notvalid.com>: Feb 12 10:14PM I am trying to get values from the whole : 1 - max(unsigned long long) range. But this code (which many recommend on the internet) just does not seem to give small number never. the range it produces (128 numbers) is always something like: 153348556926869012 - 18291104122139120324 ( 153348556926869012 18291104122139120324 ) As you can see it keep giving ONLY big numbers. It never give numbers like 9887. Why? How can I get values from the whole range? Thanks. Here is the code I am using (mi and ma are the lower and upper range or the results): const int zobristSize = 128; uint64_t zobrist[zobristSize]; std::random_device rd; std::mt19937_64 e2(std::random_device{}()); // 2723506774205678741 std::uniform_int_distribution<unsigned long long> dist(1, (std::numeric_limits<unsigned long long>::max)()); for (int n = 0; n < zobristSize; ++n) { zobrist[n] = 0; } uint64_t mi = ((std::numeric_limits<unsigned long long>::max)() - 100); uint64_t ma= 0; for (int n = 0; n < zobristSize; ++n) { // eatch value must not be before in the list while (true) { zobrist[n] = dist(e2); for (int i = 0; i < zobristSize; ++i) if (i != n && zobrist[n] == zobrist[i]) continue; break; } if (zobrist[n] < mi) mi = zobrist[n]; if (zobrist[n] > ma) ma = zobrist[n]; } |
"Rick C. Hodgin" <rick.c.hodgin@gmail.com>: Feb 12 05:11AM -0800 That still small voice you hear on the inside, the one drawing you from within, reminding you of the things you should be doing, and pointing out the things you shouldn't be doing ... listen to it. That voice was put there by God to guide you into all rightness, and away from everything wrong, hurtful and harmful (to yourself and others). Even though you've done hurtful and harmful things to others, God still wants to forgive you. He still loves you. He still wants to turn your life around and give it to Him, to follow after the works of truth and light, rather than pursuits of self-interest in darkness. We all need each other. We need to help each other become the full and rich people we can be. And we need God to help us overcome those things we cannot overcome on our own. Go to church each week. Learn about Jesus Christ. Learn what it means to seek after and pursue that still, small voice on the inside, rather than continuing to drown it out with other things, ignoring it hoping it will go away. This is your time to step forward in faith, to take heed of His inner call, to answer that call and pursue Him to that end He has for you, even forgiveness of your sin, and eternal life in Heaven in a body like the angels, beautiful, young, and strong. A life you never imagined awaits you in pursuit of Him. He redeems you and restores you to life (spiritual life), such that new things abound within your new man existence. It is absolutely beyond that which you could imagine, because it's all completely new, through the new man nature, and the new life after the spirit. God loves you, and will forgive you. Just ask Him to forgive you from where you are. He does the rest. And then make the real conscious choice to listen to that inner voice, to go to church, to say no to sin in your life, and yes to holiness and pursuits by which you help others. We have weaknesses as individuals, but we are strong together. Go to church and be part of that community of strength, remembering that the same enemy at work out here in the world, also tries with extra effort to gain footholds in the church. You must maintain your integrity and focus on Him first, and other things second, and then also teach and gently remind those in the church the same. Lead them continually back to where they should be, as He leads you from within. Don't be prideful in your new faith. Remember from where you came and help others to come to forgiveness in Jesus in the like manner He forgave you, by having heard this message by spreading it and by teaching people about Him. We need Him in our lives. First, and out front. He is our Redeemer. Our Salvation. Our Guide. Our Teacher. And He is also our Friend. Never let the enemy's lies convince you ahead of the truth. Remain in Him, focused, and teaching and rebuking, being ready to also be rebuked should you open your mouth and teach something falsely in ignorance. He gently guides all of us down the straight and narrow path. Because He loves us. Love you, Rick C. Hodgin PS - For those who hear His call and know what I'm talking about, welcome. The Kingdom of God awaits you. May you serve Him always in honest integrity, with a right mind and focus on leading more people to His Son Jesus, so they can also be forgiven and be saved. Always done in much peace and much love. |
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Feb 12 06:09PM On 12/02/2017 13:11, Rick C. Hodgin wrote: [bullshit (tl;dr) snipped] Please fuck off you proselytizing obtuse cunt. Nobody is interested in what you are preaching except those one or two idiots who ALREADY agree with you. /Flibble |
"Rick C. Hodgin" <rick.c.hodgin@gmail.com>: Feb 12 10:49AM -0800 Mr Flibble wrote: > [expletives deleted] Read this short verse, Leigh: http://biblehub.com/kjv/revelation/22-11.htm 11 He that is unjust, let him be unjust still: and he which is filthy, let him be filthy still: and he that is righteous, let him be righteous still: and he that is holy, let him be holy still. Why? 12 And, behold, I come quickly; and my reward is with me, to give every man according as his work shall be. Each person is going to receive just as they gave, Leigh. Repent and receive life. Continue on your current path and it means your very existence. Cast into a lake of burning fire. Your choice. Jesus, I, and every Christian wants you to choose the path of forgiveness and salvation. We want you to shine on in Heaven as the beautiful and remarkable creation of God you can be in Christ. Thank you, Rick C. Hodgin |
Prroffessorr Fir Kenobi <profesor.fir@gmail.com>: Feb 12 12:14AM -0800 (i know this is oftopic but im searching for some coder experienced in programming sound on pc - maybe some here? if no skip that message, tnx) i dont know how exactly sound cards on computers work (now and then) i know i can send a .wav with any sample to be played but i heard it will be played with some delay.. (this delay comes form driver or hardware, i dont know, probably driver maybe) .. i heard that this delay is even in a range of miliseconds (it means is quite big) [im not sure though as to this information and searching for more info] whai if i would do instant realtime playing in my games (prototypes) .. i mean if game is runing with high fps (like 120 or 160 ) i want to calculate and play (and change) sound in each frame [it may sound even like chaos but i would like to test that] also i would like to have no human sensible delays, i want source of sound physicaly coordinated with frame displayed (imagine for example that movie is played at 120 hz and sound is based on color of current frame and is played with coordinated with this frame display) is it possible to do that? |
"Öö Tiib" <ootiib@hot.ee>: Feb 12 04:12AM -0800 On Sunday, 12 February 2017 10:15:01 UTC+2, Prroffessorr Fir Kenobi wrote: > (i know this is oftopic but im searching for some coder experienced > in programming sound on pc - maybe some here? I have tried SDL_mixer some years ago and it worked. I wanted to add sound effects to a program. It worked fine for what I needed and same code (and same files) worked on Mac, Windows and Linux and it all felt quite easy. If you need experienced people and knowledge of SDL then ... Forum of SDL: https://forums.libsdl.org/ Wiki of SDL: https://wiki.libsdl.org/ |
Prroffessorr Fir Kenobi <profesor.fir@gmail.com>: Feb 12 10:37AM -0800 W dniu niedziela, 12 lutego 2017 13:12:14 UTC+1 użytkownik Öö Tiib napisał: > If you need experienced people and knowledge of SDL then ... > Forum of SDL: https://forums.libsdl.org/ > Wiki of SDL: https://wiki.libsdl.org/ ok i will check, here also a bit more words of description what i want: (quotation from myself) "imagine i got arcade game with say 5 of 2d starships firing a lot of bulets rapidly (like machine gun fire) (say each one ship fires a bullets that sound in his own sound (different sounds) say also that in each series (say for 1..50 bullets in one seria) each bullets have slightly different sounds - and assume each bullet sound is short (dont know 1/10 second sound) need i just precalculate 5 wav buffers (each one for each chip) in each buffer precalculate sound for each seria of bullets (it would be 5 buffers of 50 x 0.1 sec of sounds) then just point the pointer to location for each ship/bullet and command it to play? i wonder if it would all play and mix with no visible delay - where to find some forum for exact answer and how to measure it? (im not quite can to open project and try to test it right now but im very curious for posible delays and problems here - as i would like to do such kind of realtime generated sounds not jus play rare long tunes) " |
Manfred <noname@invalid.add>: Feb 10 07:07PM +0100 On 02/10/2017 05:19 PM, Öö Tiib wrote: > On Friday, 10 February 2017 14:05:27 UTC+2, Chris Vine wrote: >> On Fri, 10 Feb 2017 03:26:05 -0800 (PST) >> Öö Tiib <ootiib@hot.ee> wrote: <snip> >> raised the issue of "cache misses", he wanted to know Christopher's >> views on designing for locality, and that is about performance. You >> get the job by dealing with the issues put to you. I think you also get the job by giving exhaustive answers. The points above seem pretty much on topic to me. <snip> > until I find out. Code can be edited and will be edited and if I don't yet > know nature of data clearly then there is no way how I can ensure that it > performs optimally. I agree that the first rationale for the choice is the nature of data, as you correctly indicated. I may add that it follows from your list that you would pick case 6) unless there is polymorphism or the vector does not own the Employees, which happens to be the most performing solution (not surprisingly, since C++ usually likes the simplest solution to be the most performing as well) |
woodbrian77@gmail.com: Feb 11 10:42PM -0800 I was looking into how to serialize std::variant objects but have hit a problem. #include <variant> int main () { constexpr ::std::variant<int, float> var = 3.3f; auto extract = ::std::get<var.index()>(var); } I have to make var constexpr in order to be able to use var.index() with std::get. But after I do that I can't write var = 7; If a variant isn't declared constexpr, I don't know how to get the value out of it. I'm new to constexpr stuff. Is there something I'm missing? Thanks in advance. Brian Ebenezer Enterprises - In G-d we trust. http://webEbenezer.net |
"Öö Tiib" <ootiib@hot.ee>: Feb 12 01:04AM -0800 > If a variant isn't declared constexpr, I don't know how to get the > value out of it. I'm new to constexpr stuff. Is there something > I'm missing? Thanks in advance. C++ is strongly typed language and variants, unions and/or ellipsis arguments can't magically make it to go away. The 'get' needs to know what type it returns compile time so if you can't tell it compile time then you can't use it. If you still want to use 'std::get' (I personally prefer visitors) then use ordinary 'if' (or 'switch' or the like) to ensure beforehand that you know what type that 'get' returns: std::variant<int, std::string> v = "abc"; // no constexpr if ( v.index() == 1 ) { // here we know that get returns string auto extract = std::get<1>(v); } |
"Chris M. Thomasson" <invalid@invalid.invalid>: Feb 11 08:18PM -0800 On 2/11/2017 9:54 AM, Paavo Helde wrote: > while some other NUMA node is overloaded. But it looks like this is not > so easy to achieve in general, as the jobs I am binding can be in > different processes and their number and duration are not known in advance. Hummmm.... For now, think of binding a really low priority thread per NUMA node. When it wakes, it increments a counter, and checks it for a maxima. Okay, when this it hit, the node can say its in a LOW condition scenario or something, reset the counter and repeat. Now, this is highly contrived, but iirc, it worked fairly well as entropy for some heuristics during runtime of system. The low priority thread can decide to steal the shi% out of higher chunks of work when it hits the threshold in a work-stealing/requesting hybrid sync setup. I will try to find some more info, that is escaping me right now. Sorry Paavo. ;^o > than me. Actually I have tried to bind threads to single PU-s on > non-NUMA systems and the performance stayed the same or went worse, > depending on the OS/hardware. Agreed. Sometimes, very rarely, it can be good to separate GC threads, or proxy gc counting threads. Will try to remember. This was back a damn decade ago. Shi%, I am getting old. ;^o Yikes! |
Robert Wessel <robertwessel2@yahoo.com>: Feb 12 02:48AM -0600 On Fri, 10 Feb 2017 21:18:30 -0800, "Chris M. Thomasson" >> single NUMA node (because profiling shows there is no point to let it >> spread across nodes, it would be just wasting computer resources). >Indeed. Sharing across NUMA nodes should be avoided like the damn plague! FSVO "plague". The whole point of NUMA is to allow some level of intra-node sharing with significantly lower latency than across a cluster. If you don't have/need that, then why are you running on an expensive NUMA box rather than on a cheap cluster? Which is not to detract from your point, which is that data sharing between nodes has a very significant penalty compared to items held (exclusively) local to a node. |
Robert Wessel <robertwessel2@yahoo.com>: Feb 12 01:52AM -0600 On Fri, 10 Feb 2017 14:57:49 GMT, scott@slp53.sl.home (Scott Lurndal) wrote: >e.g., something similar to: >constexpr >unsigned int log2(uint64_t n) { return (n<=1) ? 0: (64-__builtin_clzll(n-1)); }; That's not the same thing - the above uses pow(), because FLT_RADIX does not have to be 2. And it's its an exponential function, not a logarithm. If you're implying that you could use a logarithm as a part of that computation, assuming, something like: a**b = 2 ** (a * lg(b)) and generating the logarithm with a clz, and then the exponentiation with a left shit. That doesn't work because no integer approximation of the lg will be close enough to create anywhere near the correct value for the exponentiation. An exception being where (a) is a power of two. Now while I suppose someone could define a pow() that is, itself, a constexpr, I've never seen it done. |
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