Sunday, February 12, 2017

Digest for comp.lang.c++@googlegroups.com - 24 updates in 9 topics

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: