Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
Alchemy Viewer
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Iterations
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Locked files
Deploy
Releases
Package registry
Operate
Terraform modules
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Silent mode is enabled
All outbound communications are blocked.
Learn more
.
Show more breadcrumbs
Alchemy Viewer
Alchemy Viewer
Commits
3d718db9
Commit
3d718db9
authored
5 years ago
by
Rye Mutt
Browse files
Options
Downloads
Patches
Plain Diff
Cleanup and optimize LLMaterialID to be trivially copy/movable and introduce SIMD operators
parent
51325421
No related branches found
No related tags found
No related merge requests found
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
indra/llprimitive/llmaterialid.cpp
+0
-75
0 additions, 75 deletions
indra/llprimitive/llmaterialid.cpp
indra/llprimitive/llmaterialid.h
+108
-14
108 additions, 14 deletions
indra/llprimitive/llmaterialid.h
with
108 additions
and
89 deletions
indra/llprimitive/llmaterialid.cpp
+
0
−
75
View file @
3d718db9
...
@@ -35,11 +35,6 @@
...
@@ -35,11 +35,6 @@
const
LLMaterialID
LLMaterialID
::
null
;
const
LLMaterialID
LLMaterialID
::
null
;
LLMaterialID
::
LLMaterialID
()
{
clear
();
}
LLMaterialID
::
LLMaterialID
(
const
LLSD
&
pMaterialID
)
LLMaterialID
::
LLMaterialID
(
const
LLSD
&
pMaterialID
)
{
{
llassert
(
pMaterialID
.
isBinary
());
llassert
(
pMaterialID
.
isBinary
());
...
@@ -56,61 +51,11 @@ LLMaterialID::LLMaterialID(const void* pMemory)
...
@@ -56,61 +51,11 @@ LLMaterialID::LLMaterialID(const void* pMemory)
set
(
pMemory
);
set
(
pMemory
);
}
}
LLMaterialID
::
LLMaterialID
(
const
LLMaterialID
&
pOtherMaterialID
)
{
copyFromOtherMaterialID
(
pOtherMaterialID
);
}
LLMaterialID
::
LLMaterialID
(
const
LLUUID
&
lluid
)
LLMaterialID
::
LLMaterialID
(
const
LLUUID
&
lluid
)
{
{
set
(
lluid
.
mData
);
set
(
lluid
.
mData
);
}
}
LLMaterialID
::~
LLMaterialID
()
{
}
bool
LLMaterialID
::
operator
==
(
const
LLMaterialID
&
pOtherMaterialID
)
const
{
return
(
compareToOtherMaterialID
(
pOtherMaterialID
)
==
0
);
}
bool
LLMaterialID
::
operator
!=
(
const
LLMaterialID
&
pOtherMaterialID
)
const
{
return
(
compareToOtherMaterialID
(
pOtherMaterialID
)
!=
0
);
}
bool
LLMaterialID
::
operator
<
(
const
LLMaterialID
&
pOtherMaterialID
)
const
{
return
(
compareToOtherMaterialID
(
pOtherMaterialID
)
<
0
);
}
bool
LLMaterialID
::
operator
<=
(
const
LLMaterialID
&
pOtherMaterialID
)
const
{
return
(
compareToOtherMaterialID
(
pOtherMaterialID
)
<=
0
);
}
bool
LLMaterialID
::
operator
>
(
const
LLMaterialID
&
pOtherMaterialID
)
const
{
return
(
compareToOtherMaterialID
(
pOtherMaterialID
)
>
0
);
}
bool
LLMaterialID
::
operator
>=
(
const
LLMaterialID
&
pOtherMaterialID
)
const
{
return
(
compareToOtherMaterialID
(
pOtherMaterialID
)
>=
0
);
}
LLMaterialID
&
LLMaterialID
::
operator
=
(
const
LLMaterialID
&
pOtherMaterialID
)
{
copyFromOtherMaterialID
(
pOtherMaterialID
);
return
(
*
this
);
}
bool
LLMaterialID
::
isNull
()
const
{
return
(
compareToOtherMaterialID
(
LLMaterialID
::
null
)
==
0
);
}
const
U8
*
LLMaterialID
::
get
()
const
const
U8
*
LLMaterialID
::
get
()
const
{
{
return
mID
;
return
mID
;
...
@@ -161,28 +106,8 @@ std::ostream& operator<<(std::ostream& s, const LLMaterialID &material_id)
...
@@ -161,28 +106,8 @@ std::ostream& operator<<(std::ostream& s, const LLMaterialID &material_id)
return
s
;
return
s
;
}
}
void
LLMaterialID
::
parseFromBinary
(
const
LLSD
::
Binary
&
pMaterialID
)
void
LLMaterialID
::
parseFromBinary
(
const
LLSD
::
Binary
&
pMaterialID
)
{
{
llassert
(
pMaterialID
.
size
()
==
(
MATERIAL_ID_SIZE
*
sizeof
(
U8
)));
llassert
(
pMaterialID
.
size
()
==
(
MATERIAL_ID_SIZE
*
sizeof
(
U8
)));
memcpy
(
mID
,
&
pMaterialID
[
0
],
MATERIAL_ID_SIZE
*
sizeof
(
U8
));
memcpy
(
mID
,
&
pMaterialID
[
0
],
MATERIAL_ID_SIZE
*
sizeof
(
U8
));
}
}
void
LLMaterialID
::
copyFromOtherMaterialID
(
const
LLMaterialID
&
pOtherMaterialID
)
{
memcpy
(
mID
,
pOtherMaterialID
.
get
(),
MATERIAL_ID_SIZE
*
sizeof
(
U8
));
}
int
LLMaterialID
::
compareToOtherMaterialID
(
const
LLMaterialID
&
pOtherMaterialID
)
const
{
int
retVal
=
0
;
for
(
unsigned
int
i
=
0U
;
(
retVal
==
0
)
&&
(
i
<
static_cast
<
unsigned
int
>
(
MATERIAL_ID_SIZE
/
sizeof
(
U32
)));
++
i
)
{
const
U32
*
thisValue
=
reinterpret_cast
<
const
U32
*>
(
&
get
()[
i
*
sizeof
(
U32
)]);
const
U32
*
otherValue
=
reinterpret_cast
<
const
U32
*>
(
&
pOtherMaterialID
.
get
()[
i
*
sizeof
(
U32
)]);
retVal
=
((
*
thisValue
<
*
otherValue
)
?
-
1
:
((
*
thisValue
>
*
otherValue
)
?
1
:
0
));
}
return
retVal
;
}
This diff is collapsed.
Click to expand it.
indra/llprimitive/llmaterialid.h
+
108
−
14
View file @
3d718db9
...
@@ -30,30 +30,126 @@
...
@@ -30,30 +30,126 @@
#define MATERIAL_ID_SIZE 16
#define MATERIAL_ID_SIZE 16
#include
<string>
#include
<string>
#include
<immintrin.h>
#include
"llsd.h"
#include
"llsd.h"
class
LLMaterialID
class
LLMaterialID
{
{
public:
public:
LLMaterialID
();
LLMaterialID
()
=
default
;
LLMaterialID
(
const
LLSD
&
pMaterialID
);
LLMaterialID
(
const
LLSD
&
pMaterialID
);
LLMaterialID
(
const
LLSD
::
Binary
&
pMaterialID
);
LLMaterialID
(
const
LLSD
::
Binary
&
pMaterialID
);
LLMaterialID
(
const
void
*
pMemory
);
LLMaterialID
(
const
void
*
pMemory
);
LLMaterialID
(
const
LLMaterialID
&
pOtherMaterialID
);
LLMaterialID
(
const
LLUUID
&
lluid
);
LLMaterialID
(
const
LLUUID
&
lluid
);
~
LLMaterialID
();
bool
operator
==
(
const
LLMaterialID
&
pOtherMaterialID
)
const
;
// BEGIN BOOST
bool
operator
!=
(
const
LLMaterialID
&
pOtherMaterialID
)
const
;
// Contains code from the Boost Library with license below.
/*
* Copyright Andrey Semashev 2013.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*/
LL_FORCE_INLINE
__m128i
load_unaligned_si128
(
const
U8
*
p
)
const
{
#if defined(AL_AVX)
return
_mm_lddqu_si128
(
reinterpret_cast
<
const
__m128i
*>
(
p
));
#else
return
_mm_loadu_si128
(
reinterpret_cast
<
const
__m128i
*>
(
p
));
#endif
}
bool
operator
==
(
const
LLMaterialID
&
rhs
)
const
{
__m128i
mm_left
=
load_unaligned_si128
(
mID
);
__m128i
mm_right
=
load_unaligned_si128
(
rhs
.
mID
);
__m128i
mm_cmp
=
_mm_cmpeq_epi32
(
mm_left
,
mm_right
);
#if defined(AL_AVX)
return
_mm_test_all_ones
(
mm_cmp
);
#else
return
_mm_movemask_epi8
(
mm_cmp
)
==
0xFFFF
;
#endif
}
bool
operator
!=
(
const
LLMaterialID
&
rhs
)
const
{
return
!
((
*
this
)
==
rhs
);
}
bool
operator
<
(
const
LLMaterialID
&
rhs
)
const
{
__m128i
mm_left
=
_mm_lddqu_si128
(
reinterpret_cast
<
const
__m128i
*>
(
mID
));
__m128i
mm_right
=
_mm_lddqu_si128
(
reinterpret_cast
<
const
__m128i
*>
(
rhs
.
mID
));
// To emulate lexicographical_compare behavior we have to perform two comparisons - the forward and reverse one.
// Then we know which bytes are equivalent and which ones are different, and for those different the comparison results
// will be opposite. Then we'll be able to find the first differing comparison result (for both forward and reverse ways),
// and depending on which way it is for, this will be the result of the operation. There are a few notes to consider:
//
// 1. Due to little endian byte order the first bytes go into the lower part of the xmm registers,
// so the comparison results in the least significant bits will actually be the most signigicant for the final operation result.
// This means we have to determine which of the comparison results have the least significant bit on, and this is achieved with
// the "(x - 1) ^ x" trick.
// 2. Because there is only signed comparison in SSE/AVX, we have to invert byte comparison results whenever signs of the corresponding
// bytes are different. I.e. in signed comparison it's -1 < 1, but in unsigned it is the opposite (255 > 1). To do that we XOR left and right,
// making the most significant bit of each byte 1 if the signs are different, and later apply this mask with another XOR to the comparison results.
// 3. pcmpgtw compares for "greater" relation, so we swap the arguments to get what we need.
const
__m128i
mm_signs_mask
=
_mm_xor_si128
(
mm_left
,
mm_right
);
__m128i
mm_cmp
=
_mm_cmpgt_epi8
(
mm_right
,
mm_left
),
mm_rcmp
=
_mm_cmpgt_epi8
(
mm_left
,
mm_right
);
bool
operator
<
(
const
LLMaterialID
&
pOtherMaterialID
)
const
;
mm_cmp
=
_mm_xor_si128
(
mm_signs_mask
,
mm_cmp
);
bool
operator
<=
(
const
LLMaterialID
&
pOtherMaterialID
)
const
;
mm_rcmp
=
_mm_xor_si128
(
mm_signs_mask
,
mm_rcmp
);
bool
operator
>
(
const
LLMaterialID
&
pOtherMaterialID
)
const
;
bool
operator
>=
(
const
LLMaterialID
&
pOtherMaterialID
)
const
;
LLMaterialID
&
operator
=
(
const
LLMaterialID
&
pOtherMaterialID
);
uint32_t
cmp
=
static_cast
<
uint32_t
>
(
_mm_movemask_epi8
(
mm_cmp
)),
rcmp
=
static_cast
<
uint32_t
>
(
_mm_movemask_epi8
(
mm_rcmp
)
);
bool
isNull
()
const
;
cmp
=
(
cmp
-
1u
)
^
cmp
;
rcmp
=
(
rcmp
-
1u
)
^
rcmp
;
return
static_cast
<
uint16_t
>
(
cmp
)
<
static_cast
<
uint16_t
>
(
rcmp
);
}
bool
operator
>
(
const
LLMaterialID
&
rhs
)
const
{
return
rhs
<
(
*
this
);
}
bool
operator
<=
(
const
LLMaterialID
&
rhs
)
const
{
return
!
(
rhs
<
(
*
this
));
}
bool
operator
>=
(
const
LLMaterialID
&
rhs
)
const
{
return
!
((
*
this
)
<
rhs
);
}
bool
isNull
()
const
{
__m128i
mm
=
load_unaligned_si128
(
mID
);
#if defined(AL_AVX)
return
_mm_test_all_zeros
(
mm
,
mm
)
!=
0
;
#else
mm
=
_mm_cmpeq_epi8
(
mm
,
_mm_setzero_si128
());
return
_mm_movemask_epi8
(
mm
)
==
0xFFFF
;
#endif
}
inline
size_t
hash
()
const
{
size_t
seed
=
0
;
for
(
U8
i
=
0
;
i
<
4
;
++
i
)
{
seed
^=
static_cast
<
size_t
>
(
mID
[
i
*
4
])
+
0x9e3779b9
+
(
seed
<<
6
)
+
(
seed
>>
2
);
seed
^=
static_cast
<
size_t
>
(
mID
[
i
*
4
+
1
])
+
0x9e3779b9
+
(
seed
<<
6
)
+
(
seed
>>
2
);
seed
^=
static_cast
<
size_t
>
(
mID
[
i
*
4
+
2
])
+
0x9e3779b9
+
(
seed
<<
6
)
+
(
seed
>>
2
);
seed
^=
static_cast
<
size_t
>
(
mID
[
i
*
4
+
3
])
+
0x9e3779b9
+
(
seed
<<
6
)
+
(
seed
>>
2
);
}
return
seed
;
}
// END BOOST
const
U8
*
get
()
const
;
const
U8
*
get
()
const
;
void
set
(
const
void
*
pMemory
);
void
set
(
const
void
*
pMemory
);
...
@@ -68,10 +164,8 @@ class LLMaterialID
...
@@ -68,10 +164,8 @@ class LLMaterialID
private
:
private
:
void
parseFromBinary
(
const
LLSD
::
Binary
&
pMaterialID
);
void
parseFromBinary
(
const
LLSD
::
Binary
&
pMaterialID
);
void
copyFromOtherMaterialID
(
const
LLMaterialID
&
pOtherMaterialID
);
int
compareToOtherMaterialID
(
const
LLMaterialID
&
pOtherMaterialID
)
const
;
U8
mID
[
MATERIAL_ID_SIZE
];
U8
mID
[
MATERIAL_ID_SIZE
]
=
{}
;
}
;
}
;
#endif // LL_LLMATERIALID_H
#endif // LL_LLMATERIALID_H
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment