Boost.MultiIndex question on merge
Hello, Are there way to merge two multiindex objects ? suppouse we have : struct strData{ int id; float a, b; strData(int id_, float a_, float b_):a(a_),b(b_),id(id_){} }; typedef multi_index_container< strData, indexed_by< ordered_unique< tag<id>, BOOST_MULTI_INDEX_MEMBER(strData,int,id)>, ordered_non_unique< tag<snap>,BOOST_MULTI_INDEX_MEMBER(strData,float,a)> > > data_setA, data_setB; Are there way to do: data_setA.merge(data_setB) ? thank you beforehand. Arman. -- View this message in context: http://www.nabble.com/Boost.MultiIndex-question-on-merge-tp23277496p23277496... Sent from the Boost - Users mailing list archive at Nabble.com.
why not using an stl algorithm? If you use ordered_non_unique you can use
the for_each algorithms with an inserter functor.
Ovanes
On Tue, Apr 28, 2009 at 3:46 PM, arm2arm
Hello, Are there way to merge two multiindex objects ? suppouse we have :
struct strData{ int id; float a, b; strData(int id_, float a_, float b_):a(a_),b(b_),id(id_){} };
typedef multi_index_container< strData, indexed_by< ordered_unique< tag<id>, BOOST_MULTI_INDEX_MEMBER(strData,int,id)>, ordered_non_unique< tag<snap>,BOOST_MULTI_INDEX_MEMBER(strData,float,a)>
data_setA, data_setB;
Are there way to do:
data_setA.merge(data_setB) ?
thank you beforehand. Arman. -- View this message in context: http://www.nabble.com/Boost.MultiIndex-question-on-merge-tp23277496p23277496... Sent from the Boost - Users mailing list archive at Nabble.com.
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
Thanks for quick response insert solves the problem. Yes the typedef is a typo, due to copy and paste, sorry for that ;) To: Ovanes Are there gain in the speed if I would use the for_each? I am always avoiding to use for_each to allow the compiler (like INTEL) auto-parallelize the regions. But for this particular case Is not a issue. Arman. Ovanes Markarian wrote:
why not using an stl algorithm? If you use ordered_non_unique you can use the for_each algorithms with an inserter functor.
Ovanes
On Tue, Apr 28, 2009 at 3:46 PM, arm2arm
wrote: Hello, Are there way to merge two multiindex objects ? suppouse we have :
struct strData{ int id; float a, b; strData(int id_, float a_, float b_):a(a_),b(b_),id(id_){} };
typedef multi_index_container< strData, indexed_by< ordered_unique< tag<id>, BOOST_MULTI_INDEX_MEMBER(strData,int,id)>, ordered_non_unique< tag<snap>,BOOST_MULTI_INDEX_MEMBER(strData,float,a)>
data_setA, data_setB;
Are there way to do:
data_setA.merge(data_setB) ?
thank you beforehand. Arman. -- View this message in context: http://www.nabble.com/Boost.MultiIndex-question-on-merge-tp23277496p23277496... Sent from the Boost - Users mailing list archive at Nabble.com.
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
-- View this message in context: http://www.nabble.com/Boost.MultiIndex-question-on-merge-tp23277496p23278989... Sent from the Boost - Users mailing list archive at Nabble.com.
On Tue, Apr 28, 2009 at 5:05 PM, arm2arm
To: Ovanes Are there gain in the speed if I would use the for_each? I am always avoiding to use for_each to allow the compiler (like INTEL) auto-parallelize the regions. But for this particular case Is not a issue.
to be honest, that's strange. I know from MSVC that using std::algorithms allows parallelisation. e.g. using std::find of a 32bit numeric value in a vector runs up to 4 times faster, due to XMM register optimization. Copying out the std::find loop implemation runs slower, since the compiler does not know how the vector pointed by pointer/iterator is aligned. It is pretty well explained here: http://www.agner.org/optimize/optimizing_cpp.pdf Chapter 11. My experiments with MSVC 2003 & 2005 show that searching for a number (with is not present in the vector) in a loop copied from find impl is 4 times slower as using find itself. I am curious how it is with Intel compiler. IMO STL algorithms delivered with compiler are pretty well optimized for that particular compiler version. If you write your loop, it is for sure not faster as comaprible STL algo distributed with the compiler. Does Intel explicitly state that they do not optimize STL code and it is not parallel nor the STL does not use XMM registers? Thanks, Ovanes
Thanks Ovanes for explanations, I did not touched MSVC ages currently I am using g++ and icpc: Probably intel also provides its own STL optimized library, I am not an expert, but always the fast gooling gives that in the intel presentations they avoiding usage of for_each, I will try to bench the part of the code to see which approach is faster in my case insert or for_each. But I am running in to trouble with inserter: struct strData{ int id; float a, b; strData(int id_, float a_, float b_):a(a_),b(b_),id(id_){} }; typedef multi_index_container< strData, indexed_by< ordered_unique< tag<id>, BOOST_MULTI_INDEX_MEMBER(strData,int,id)>, ordered_non_unique< tag<snap>,BOOST_MULTI_INDEX_MEMBER(strData,float,a)>
indexed_data_type;
indexed_data_type data_setA, data_setB;// we need append setB to setA { scoped_timer timeme("merge by INSERT: "); data_setA.insert(data_setB.begin(), data_setB.end()); } { scoped_timer timeme("merge by FOR_EACH: "); std::for_each( data_setB.begin(), data_setB.end(),std::inserter(data_setA)); } The compiler gives long error on: error: no matching function for call to 'inserter(boost::multi_index::multi_index_container etc.... What is the correct syntax of the inserter with multi_index_container ? Thanks Arman. Ovanes Markarian wrote:
On Tue, Apr 28, 2009 at 5:05 PM, arm2arm
wrote: To: Ovanes Are there gain in the speed if I would use the for_each? I am always avoiding to use for_each to allow the compiler (like INTEL) auto-parallelize the regions. But for this particular case Is not a issue.
to be honest, that's strange. I know from MSVC that using std::algorithms allows parallelisation.
e.g. using std::find of a 32bit numeric value in a vector runs up to 4 times faster, due to XMM register optimization. Copying out the std::find loop implemation runs slower, since the compiler does not know how the vector pointed by pointer/iterator is aligned. It is pretty well explained here: http://www.agner.org/optimize/optimizing_cpp.pdf Chapter 11. My experiments with MSVC 2003 & 2005 show that searching for a number (with is not present in the vector) in a loop copied from find impl is 4 times slower as using find itself. I am curious how it is with Intel compiler.
IMO STL algorithms delivered with compiler are pretty well optimized for that particular compiler version. If you write your loop, it is for sure not faster as comaprible STL algo distributed with the compiler. Does Intel explicitly state that they do not optimize STL code and it is not parallel nor the STL does not use XMM registers?
Thanks, Ovanes
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
-- View this message in context: http://www.nabble.com/Boost.MultiIndex-question-on-merge-tp23277496p23282660... Sent from the Boost - Users mailing list archive at Nabble.com.
________________________________________ De: boost-users-bounces@lists.boost.org [boost-users-bounces@lists.boost.org] En nombre de arm2arm [arm2arm@gmail.com] Enviado el: martes, 28 de abril de 2009 19:42 Para: boost-users@lists.boost.org Asunto: Re: [Boost-users] Boost.MultiIndex question on merge
But I am running in to trouble with inserter: [...] std::for_each( data_setB.begin(), data_setB.end(),std::inserter(data_setA));
I think the correct way to use std::inserter is std::copy( data_setB.begin(),data_setB.end(), std::inserter(data_setA,data_setA.end())); Joaquín M López Muñoz Telefónica, Investigación y Desarrollo
{ scoped_timer timeme("merge by FOR_EACH: "); std::for_each( data_setB.begin(), data_setB.end(),std::inserter(data_setA)); }
The compiler gives long error on: error: no matching function for call to 'inserter(boost::multi_index::multi_index_container etc....
What is the correct syntax of the inserter with multi_index_container ?
std::for_each(data_setB.begin(), data_setB.end(), std::inserter(data_setA, data_setA.end()));
Ovanes Markarian
On Tue, Apr 28, 2009 at 5:05 PM, arm2arm
wrote: To: Ovanes Are there gain in the speed if I would use the for_each? I am always avoiding to use for_each to allow the compiler (like INTEL) auto-parallelize the regions. But for this particular case Is not a issue.
to be honest, that's strange. I know from MSVC that using std::algorithms allows parallelisation.
I find this very strange. Gcc accepted some parallelized STL implementation too in recent years, and I always questioned it. For example, 25.1.1/1 in c++98 (for_each def'n): Effects: Applies f to the result of dereferencing every iterator in the range [first, last), starting from first and proceeding to last - 1. How could you possibly parallelize that? It's defined to operate in series. I guess if the compiler could prove that `f' had no side effects, and there were no volatiles involved, it might be possible (is that strong enough to prove that that execution order is irrelevant? hrm..) It seems like the former would run up against solving the aliasing problem, though. What am I missing here? (Granted, I can't recall the last time I wrote a for_each that *relied* on that execution order. Further, I could probably be convinced that requiring a particular ordering here was a specification mistake. Still, a standard is a standard.) -tom
On Thu, Apr 30, 2009 at 7:12 AM, tom fogal
I find this very strange. Gcc accepted some parallelized STL implementation too in recent years, and I always questioned it. For example, 25.1.1/1 in c++98 (for_each def'n):
Effects: Applies f to the result of dereferencing every iterator in the range [first, last), starting from first and proceeding to last - 1.
How could you possibly parallelize that? It's defined to operate in series. I guess if the compiler could prove that `f' had no side effects, and there were no volatiles involved, it might be possible (is that strong enough to prove that that execution order is irrelevant? hrm..) It seems like the former would run up against solving the aliasing problem, though. What am I missing here?
(Granted, I can't recall the last time I wrote a for_each that *relied* on that execution order. Further, I could probably be convinced that requiring a particular ordering here was a specification mistake. Still, a standard is a standard.)
-tom
Tom, my example was referring to find. There you use a single value to be found in the range. That allows you to make parallel comparisons. Why should it be relevant in that context if the iterator points to a volatile value or not or is volatile itself. find-algo makes a read-only operations on container sequence. In my particular example I spoke about doing comparisons in parallel. Regards, Ovanes
Ovanes Markarian
On Thu, Apr 30, 2009 at 7:12 AM, tom fogal
wrote: I find this very strange. Gcc accepted some parallelized STL implementation too in recent years, and I always questioned it. For example, 25.1.1/1 in c++98 (for_each def'n):
Effects: Applies f to the result of dereferencing every iterator in the range [first, last), starting from first and proceeding to last - 1.
How could you possibly parallelize that? It's defined to operate in series. I guess if the compiler could prove that `f' had no side effects, and there were no volatiles involved, it might be possible (is that strong enough to prove that that execution order is irrelevant? hrm..) It seems like the former would run up against solving the aliasing problem, though. What am I missing here?
(Granted, I can't recall the last time I wrote a for_each that *relied* on that execution order. Further, I could probably be convinced that requiring a particular ordering here was a specification mistake. Still, a standard is a standard.)
my example was referring to find. There you use a single value to be found in the range.
You'll note that I said `For example'. I did not claim that there did not exist a std algorithm which could not be parallelized. I intended to claim that there exists some algorithms which can only be meaningfully parallelized if one interprets the algorithm in a particular (what I would say normal) manner, as opposed to the way the standard dictates it must be. In reading 25.1 now, I'm finding very few functions which actually dictate the ordering, which is promising. However, I *am* seeing a lot of `returns the *first* <X> in the range [first, last) such that...'. This is unfortunate :(
Why should it be relevant in that context if the iterator points to a volatile value or not or is volatile itself. find-algo makes a read-only operations on container sequence.
The functor given to e.g. find_if ``shall not apply any non-constant
function *through the dereferenced iterator*'' (25/7, emph. added).
This does not preclude modifying the external environment (i.e. having
side effects). See the appended program for an example of a program
which does terribly dirty things, yet I would consider written to spec.
I'd be delighted if you or others could prove me wrong.
I didn't use volatile in the example program, but since a volatile
variable can be modified by an external entity, a `constant' function
which queries/depends on that mutable program state will see
differences in behavior for parallel vs. serial STL implementations.
Especially if that constant function then modifies the program state
itself (e.g. ++num_equal in the example).
Finally, note that the parallel STL implementation I referenced
([1] after a second of googling) reports parallelization of mutable
functions as well as non-mutable functions. However, upon further
examination I find we are in luck there! The standard explicitly
requires that std::accumulate (for example) may not have side effects.
Hopefully that (stronger) requirement will be imbued on all of the
sequence operations in the future.
Cheers,
-tom
[1]
http://gcc.gnu.org/onlinedocs/libstdc++/manual/parallel_mode.html#manual.ext...
#include <algorithm>
#include <functional>
#include <iostream>
#include <utility>
static int x = 0;
struct MyClass {
MyClass() : value(x++) {}
MyClass(int v) : value(v) {}
bool operator ==(const MyClass &c) const {
return this->value == c.value;
}
int value;
};
static MyClass initial(19), another(64);
static MyClass &aref = initial;
static int num_equal = 0;
void docrazythings(int val) {
if(val == 42) {
if(aref == another) {
aref = initial;
} else {
aref = another;
}
}
}
struct apply : public std::unary_function
participants (5)
-
arm2arm
-
Igor R
-
JOAQUIN M. LOPEZ MUÑOZ
-
Ovanes Markarian
-
tom fogal