Implement faster mju_isZeroByte.
PiperOrigin-RevId: 814148714 Change-Id: Iaf5ed9d3502eaaaee8d46a986f2db00811ae0707
This commit is contained in:
committed by
Copybara-Service
parent
401bf431b8
commit
91257896c0
@@ -1332,26 +1332,8 @@ int mju_isZero(const mjtNum* vec, int n) {
|
||||
|
||||
// return 1 if all elements are 0
|
||||
int mju_isZeroByte(const unsigned char* vec, int n) {
|
||||
size_t i = 0;
|
||||
|
||||
// unroll using 8-byte chunks
|
||||
const uint64_t* vec64 = (const uint64_t*)vec;
|
||||
size_t n64 = n / sizeof(uint64_t);
|
||||
for (; i < n64; ++i) {
|
||||
if (vec64[i]) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// remaining bytes
|
||||
i *= sizeof(uint64_t);
|
||||
for (; i < n; ++i) {
|
||||
if (vec[i]) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
if (!n || *vec) return !n;
|
||||
return memcmp(vec, vec + 1, n - 1) == 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -136,7 +136,7 @@ MJAPI int mju_isBad(mjtNum x);
|
||||
// return 1 if all elements are numerically 0 (-0.0 treated as zero)
|
||||
MJAPI int mju_isZero(const mjtNum* vec, int n);
|
||||
|
||||
// return 1 if all elements are 0x00, can be ~2x faster than mju_isZero
|
||||
// return 1 if all elements are 0x00, faster than mju_isZero
|
||||
MJAPI int mju_isZeroByte(const unsigned char* vec, int n);
|
||||
|
||||
// set integer vector to 0
|
||||
|
||||
@@ -46,6 +46,11 @@ ABSL_ATTRIBUTE_NO_TAIL_CALL static void IzZeroBenchmark(
|
||||
}
|
||||
|
||||
// Define benchmarks.
|
||||
void BM_isZeroByte_10(benchmark::State& state) {
|
||||
IzZeroBenchmark(state, 10, true);
|
||||
}
|
||||
BENCHMARK(BM_isZeroByte_10);
|
||||
|
||||
void BM_isZeroByte_1e2(benchmark::State& state) {
|
||||
IzZeroBenchmark(state, 100, true);
|
||||
}
|
||||
@@ -56,6 +61,11 @@ void BM_isZeroByte_1e5(benchmark::State& state) {
|
||||
}
|
||||
BENCHMARK(BM_isZeroByte_1e5);
|
||||
|
||||
void BM_isZero_10(benchmark::State& state) {
|
||||
IzZeroBenchmark(state, 10, false);
|
||||
}
|
||||
BENCHMARK(BM_isZero_10);
|
||||
|
||||
void BM_isZero_1e2(benchmark::State& state) {
|
||||
IzZeroBenchmark(state, 100, false);
|
||||
}
|
||||
|
||||
@@ -360,6 +360,35 @@ TEST_F(UtilMiscTest, MjuIsZero) {
|
||||
EXPECT_EQ(mju_isZeroByte((const unsigned char*)vec, sizeof(mjtNum)), 0);
|
||||
}
|
||||
|
||||
TEST_F(UtilMiscTest, MjuIsZeroByte) {
|
||||
// Zero length array
|
||||
EXPECT_TRUE(mju_isZeroByte(nullptr, 0));
|
||||
|
||||
// zero length array with non-null pointer
|
||||
unsigned char vec0[1] = {0};
|
||||
EXPECT_TRUE(mju_isZeroByte(vec0, sizeof(vec0)));
|
||||
|
||||
// one zero element array
|
||||
unsigned char vec1[1] = {0};
|
||||
EXPECT_TRUE(mju_isZeroByte(vec1, sizeof(vec1)));
|
||||
|
||||
// one non-zero element array
|
||||
unsigned char vec2[2] = {1};
|
||||
EXPECT_FALSE(mju_isZeroByte(vec2, sizeof(vec2)));
|
||||
|
||||
// Non-zero at start
|
||||
unsigned char vec3[3] = {1, 0, 0};
|
||||
EXPECT_FALSE(mju_isZeroByte(vec3, sizeof(vec3)));
|
||||
|
||||
// Non-zero at end
|
||||
unsigned char vec4[3] = {0, 0, 1};
|
||||
EXPECT_FALSE(mju_isZeroByte(vec4, sizeof(vec4)));
|
||||
|
||||
// Non-zero in middle
|
||||
unsigned char vec5[3] = {0, 1, 0};
|
||||
EXPECT_FALSE(mju_isZeroByte(vec5, sizeof(vec5)));
|
||||
}
|
||||
|
||||
// --------------------------------- Interpolation -----------------------------
|
||||
|
||||
using InterpolationTest = MujocoTest;
|
||||
|
||||
Reference in New Issue
Block a user