Problem with functions not inlining
Moderator: Ras
-
- Posts: 4052
- Joined: Thu May 15, 2008 9:57 pm
- Location: Berlin, Germany
- Full name: Sven Schüle
Re: Problem with functions not inlining
Could you show one exact example of how you use that operator& in your code?
My suspicion is that your problem may be related to the way how you have defined your operator(s).
Sven
My suspicion is that your problem may be related to the way how you have defined your operator(s).
Sven
-
- Posts: 2251
- Joined: Wed Mar 08, 2006 8:47 pm
- Location: Hattingen, Germany
Re: Problem with functions not inlining
I have that suspicion too. He has (from his first post starting this thread) binary ops as members but not friends and passing the intrinsic type as parameter (which might all be fine, but may disable inlining).Sven Schüle wrote:Could you show one exact example of how you use that operator& in your code?
My suspicion is that your problem may be related to the way how you have defined your operator(s).
Sven
Code: Select all
class xmm128i
{
private:
__m128i m_data;
...
// very simple operator ...
xmm128i operator &( __m128i const &other )
{ return xmm128i( _mm_and_si128( m_data, other ) ); }
// many more operators ...
}
Code: Select all
class xmm128i
{
private:
__m128i m_data;
...
// all kind of constructors, specially from __m128i
xmm128i(m128i a) {m_data = a;}
// very simple operator ...
friend xmm128i operator&(xmm128i const &a, xmm128i const & b) {
return xmm128i( _mm_and_si128( a.m_data, b.m_data ) );
}
-
- Posts: 388
- Joined: Sun Dec 21, 2008 6:57 pm
- Location: Washington, DC
Re: Problem with functions not inlining
Ok, home from work for the weekend and going to do some testing 
First, I'll make a small function that just tries one operations. Then I'll mess with making it a friend function and other small changes. I'll do my best to narrow it down.
Thanks, I really appreciate the help, guys. Hopefully my tests will either point me to the problem or at least give me an acceptable workaround and I won't have to pester you too much ... I'll let you know how it goes!

First, I'll make a small function that just tries one operations. Then I'll mess with making it a friend function and other small changes. I'll do my best to narrow it down.
Thanks, I really appreciate the help, guys. Hopefully my tests will either point me to the problem or at least give me an acceptable workaround and I won't have to pester you too much ... I'll let you know how it goes!
-
- Posts: 751
- Joined: Tue May 22, 2007 11:13 am
Re: Problem with functions not inlining
You could also define a member function operator&= and an ordinary (non-friend) function operator& like this:Gerd Isenberg wrote: I would try binary friends with const & xmm128 as two parameters, all necessary constructorsGerdCode: Select all
class xmm128i { private: __m128i m_data; ... // all kind of constructors, specially from __m128i xmm128i(m128i a) {m_data = a;} // very simple operator ... friend xmm128i operator&(xmm128i const &a, xmm128i const & b) { return xmm128i( _mm_and_si128( a.m_data, b.m_data ) ); }
Code: Select all
xmm128i& xmm128i::operator&=(const xmm128i& other)
{
_mm_and_si128(m_data, other.m_data);
return *this;
}
xmm128i& operator&(const xmm128i& left, const xmm128i& right)
{
return xmm128i(left) ^= right;
}
-
- Posts: 778
- Joined: Sat Jul 01, 2006 7:11 am
Re: Problem with functions not inlining
Perhaps this is your problem. http://www.talkchess.com/forum/viewtopi ... 47&t=30342
Check your command line to make sure the options you think are set are really set.
Check your command line to make sure the options you think are set are really set.
-
- Posts: 838
- Joined: Thu Jul 05, 2007 5:03 pm
- Location: British Columbia, Canada
Re: Problem with functions not inlining
This should work fine, we use similar stuff all the time for 4d float vectors with SSE2 (i.e. 16-byte-aligned Vector4 class which is a wrapper around a __m128). With Microsoft's compiler at least, "const Vector4& foo" is the right way to pass such things as parameters, and ends up getting fully inlined. The constructor from __m128 (i.e. wrap) and cast operator to __m128 (i.e. unwrap) get inlined and disappear. The member operators work fine and get properly inlined.Gerd Isenberg wrote:I have that suspicion too. He has (from his first post starting this thread) binary ops as members but not friends and passing the intrinsic type as parameter (which might all be fine, but may disable inlining).Sven Schüle wrote:Could you show one exact example of how you use that operator& in your code?
My suspicion is that your problem may be related to the way how you have defined your operator(s).
SvenI would try binary friends with const & xmm128 as two parameters, all necessary constructorsCode: Select all
class xmm128i { private: __m128i m_data; ... // very simple operator ... xmm128i operator &( __m128i const &other ) { return xmm128i( _mm_and_si128( m_data, other ) ); } // many more operators ... }
GerdCode: Select all
class xmm128i { private: __m128i m_data; ... // all kind of constructors, specially from __m128i xmm128i(m128i a) {m_data = a;} // very simple operator ... friend xmm128i operator&(xmm128i const &a, xmm128i const & b) { return xmm128i( _mm_and_si128( a.m_data, b.m_data ) ); }
If you can post a sample of the generated code, maybe someone will have a guess what is wrong with it?
Edit: also, check the compiler settings to make sure that (1) the processor type it is compiling for is the one you expect (in particular, does it know that its allowed to use SSE2 instructions?) and (2) intrinsic functions are enabled. If intrinsics are off, I can imagine the compiler generating a function call to a library function _mm_and_si128.. bleah. (just a wild guess though)
-
- Posts: 2251
- Joined: Wed Mar 08, 2006 8:47 pm
- Location: Hattingen, Germany
Re: Problem with functions not inlining
Yes, combined assignment operators return a reference and *this, since the object is not "destroyed" after leaving the scope of the function.Rein Halbersma wrote: You could also define a member function operator&= and an ordinary (non-friend) function operator& like this:
Code: Select all
xmm128i& xmm128i::operator&=(const xmm128i& other) { _mm_and_si128(m_data, other.m_data); return *this; }
Guess you mean a friend? Despite, is it correct to return a reference (or pointer) to a temporary "object", which is no longer valid outside the scope of the function? Which would be like this pointer one, which hardly looks correct to me:Rein Halbersma wrote:This should be almost guaranteed to be inlined without copy overhead because of the Return Value Optimization mechanism.Code: Select all
xmm128i& operator&(const xmm128i& left, const xmm128i& right) { return xmm128i(left) ^= right; // should be &= }
Code: Select all
friend xmm128i * operator&(const xmm128i& left, const xmm128i& right)
{
xmm128i a(left);
a &= right;
return &a; // pointer to a
}
Code: Select all
friend xmm128i operator&(const xmm128i& left, const xmm128i& right)
{
xmm128i a(left);
a &= right;
return a;
}
Code: Select all
friend xmm128i operator&(xmm128i const &a, xmm128i const & b) {
return xmm128i( _mm_and_si128( a.m_data, b.m_data ) );
}
Gerd
-
- Posts: 838
- Joined: Thu Jul 05, 2007 5:03 pm
- Location: British Columbia, Canada
Re: Problem with functions not inlining
You're right, that code looks wrong. You can't safely return a reference to a local variable, and you certainly can't return a reference to an unnamed temporary! The temporary is only in scope long enough to evaluate this expression, and then it goes away:Gerd Isenberg wrote:Guess you mean a friend? Despite, is it correct to return a reference (or pointer) to a temporary "object", which is no longer valid outside the scope of the function?Rein Halbersma wrote:This should be almost guaranteed to be inlined without copy overhead because of the Return Value Optimization mechanism.Code: Select all
xmm128i& operator&(const xmm128i& left, const xmm128i& right) { return xmm128i(left) ^= right; // should be &= }
Code: Select all
xmm128i(left) ^= right
-
- Posts: 4052
- Joined: Thu May 15, 2008 9:57 pm
- Location: Berlin, Germany
- Full name: Sven Schüle
Re: Problem with functions not inlining
There have been a couple of suggestions about how to change your code in order to get it right. It is fine to try these, of course, and it will most probably lead to a solution. However, my first goal in such cases is to understand *why* the original version does not work as expected, and this is also what I expect to be your original intention when starting this thread.Greg Strong wrote:Ok, home from work for the weekend and going to do some testing
First, I'll make a small function that just tries one operations. Then I'll mess with making it a friend function and other small changes. I'll do my best to narrow it down.
Thanks, I really appreciate the help, guys. Hopefully my tests will either point me to the problem or at least give me an acceptable workaround and I won't have to pester you too much ... I'll let you know how it goes!
So I would kindly ask you again to post an exact example of your original code where you are using your operator&, or similar. Everything else remains a mixture of feelings, suspicions and theories, and will never help to avoid making the same error again in future due to lack of understanding what *exactly* was wrong.
Sven
-
- Posts: 751
- Joined: Tue May 22, 2007 11:13 am
Re: Problem with functions not inlining
Sorry for the typo, I meant &= and not ^=. I did mean to have a non-friend operator& though. There is no reason to clutter the class interface by adding friend operators that directly manipulate data members. Stroustrup also define binary operators in terms of their compound assignment cousins in his TC++PL book.Gerd Isenberg wrote:Guess you mean a friend? Despite, is it correct to return a reference (or pointer) to a temporary "object", which is no longer valid outside the scope of the function? Which would be like this pointer one, which hardly looks correct to me:Rein Halbersma wrote:This should be almost guaranteed to be inlined without copy overhead because of the Return Value Optimization mechanism.Code: Select all
xmm128i& operator&(const xmm128i& left, const xmm128i& right) { return xmm128i(left) ^= right; // should be &= }
Gerd
Return by value would of course always work. But the return by reference should not give any problems (it does not in my code). Can you give an example where it does give a problem?