Wait, benchmarks are dumb?

This commit is contained in:
ExeVirus 2024-05-10 23:44:51 -04:00
parent 20e50029d5
commit 39c5c73e42
7 changed files with 62 additions and 19 deletions

View File

@ -74,23 +74,36 @@ void benchGetObjectsInArea(Catch::Benchmark::Chronometer &meter)
{
server::ActiveObjectMgr mgr;
size_t x;
std::vector<ServerActiveObject*> result;
std::vector<ServerActiveObject*> result, result2;
auto cb = [&x] (ServerActiveObject *obj) -> bool {
x += obj->m_static_exists ? 0 : 1;
return false;
};
fill(mgr, N);
mgr.step(0,[](ServerActiveObject*){});
// mgr.m_spatial_map.cacheUpdate([&mgr](u16 id)
// {
// auto obj = mgr.getActiveObject(id);
// if(obj != nullptr) {
// return obj->getBasePosition();
// } else {
// mgr.m_spatial_map.remove(id);
// return v3f();
// }
// });
v3f pos, off;
meter.measure([&] {
x = 0;
v3f pos = randpos();
v3f off(50, 50, 50);
pos = randpos();
off = v3f(50, 50, 50);
off[myrand_range(0, 2)] = 10;
mgr.getObjectsInArea({pos, pos + off}, result, cb);
return x;
});
REQUIRE(result.empty());
mgr.getObjectsInAreaDumb({v3f(-2000,-20,-2000), v3f(2000,60,2000)}, result2, cb);
std::cout << "numberSmart:" << result.size() << std::endl;
std::cout << "numberDumb:" << result2.size() << std::endl;
mgr.clear(); // implementation expects this
}

View File

@ -18,6 +18,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <algorithm>
#include "mg_biome.h"
#include "mg_decoration.h"
#include "emerge.h"

View File

@ -46,9 +46,9 @@ void ActiveObjectMgr::clearIf(const std::function<bool(ServerActiveObject *, u16
}
}
void ActiveObjectMgr::invalidateCachedObjectID(u16 id, v3f &last_position)
void ActiveObjectMgr::updateCachedObjectID(u16 id, v3f &last_position, v3f &new_position)
{
m_spatial_map.invalidate(id, last_position);
m_spatial_map.updatePosition(id, last_position, new_position);
}
void ActiveObjectMgr::step(
@ -154,6 +154,23 @@ void ActiveObjectMgr::getObjectsInsideRadius(const v3f &pos, float radius,
}
}
void ActiveObjectMgr::getObjectsInAreaDumb(const aabb3f &box,
std::vector<ServerActiveObject *> &result,
std::function<bool(ServerActiveObject *obj)> include_obj_cb)
{
for (auto &activeObject : m_active_objects.iter()) {
ServerActiveObject *obj = activeObject.second.get();
if (!obj)
return;
const v3f &objectpos = obj->getBasePosition();
if (!box.isPointInside(objectpos))
return;
if (!include_obj_cb || include_obj_cb(obj))
result.push_back(obj);
};
}
void ActiveObjectMgr::getObjectsInArea(const aabb3f &box,
std::vector<ServerActiveObject *> &result,
std::function<bool(ServerActiveObject *obj)> include_obj_cb)

View File

@ -38,11 +38,14 @@ public:
const std::function<void(ServerActiveObject *)> &f) override;
bool registerObject(std::unique_ptr<ServerActiveObject> obj) override;
void removeObject(u16 id) override;
void invalidateCachedObjectID(u16 id, v3f &last_position);
void updateCachedObjectID(u16 id, v3f &last_position, v3f &new_position);
void getObjectsInsideRadius(const v3f &pos, float radius,
std::vector<ServerActiveObject *> &result,
std::function<bool(ServerActiveObject *obj)> include_obj_cb);
void getObjectsInAreaDumb(const aabb3f &box,
std::vector<ServerActiveObject *> &result,
std::function<bool(ServerActiveObject *obj)> include_obj_cb);
void getObjectsInArea(const aabb3f &box,
std::vector<ServerActiveObject *> &result,
std::function<bool(ServerActiveObject *obj)> include_obj_cb);
@ -51,7 +54,6 @@ public:
f32 player_radius, const std::set<u16> &current_objects,
std::vector<u16> &added_objects);
protected:
SpatialMap m_spatial_map;
};
} // namespace server

View File

@ -18,6 +18,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
*/
#include "spatial_map.h"
#include <algorithm>
namespace server
{
@ -29,12 +30,19 @@ void SpatialMap::insert(u16 id)
}
// Invalidates upon position update
void SpatialMap::invalidate(u16 id, v3f &pos)
void SpatialMap::updatePosition(u16 id, v3f &oldPos, v3f& newPos)
{
// Try to leave early if already in the same bucket:
auto range = m_cached.equal_range(SpatialKey(newPos));
for (auto it = range.first; it != range.second; ++it) {
if (it->second == id) {
return; // all good, let's get out of here
}
}
// remove from cache, if present
bool found = false;
SpatialKey key(pos);
auto range = m_cached.equal_range(key);
range = m_cached.equal_range(SpatialKey(oldPos));
for (auto it = range.first; it != range.second; ++it) {
if (it->second == id) {
m_cached.erase(it);
@ -43,10 +51,12 @@ void SpatialMap::invalidate(u16 id, v3f &pos)
}
}
if(found) {
// place back in uncached
insert(id);
if(!found) {
m_uncached.erase(std::find(m_uncached.begin(), m_uncached.end(), id));
}
// place back in uncached
m_cached.insert(std::pair<SpatialKey,u16>(newPos, id));
}
void SpatialMap::remove(u16 id)
@ -105,7 +115,7 @@ void SpatialMap::getRelevantObjectIds(const aabb3f &box, const std::function<voi
auto absoluteRoundUp = [](f32 val) {
//return val < 0 ? floor(val) : ceil(val);}
s16 rounded = std::lround(val);
s16 remainder = (rounded & 0xF) != 0; // same as (val % 16) != 0
s16 remainder = (rounded & 0xF) != 0; // same as (val % 8) != 0
return (rounded >> 4) + ((rounded < 0) ? -remainder : remainder); // divide by 16 and round "up" the remainder
};

View File

@ -31,8 +31,7 @@ public:
// all inserted entires go into the uncached vector
void insert(u16 id);
// Invalidates upon position update or removal
void invalidate(u16 id, v3f &pos);
void updatePosition(u16 id, v3f &oldPos, v3f& newPos);
// On active_object removal, remove.
void remove(u16 id, v3f pos);

View File

@ -1589,8 +1589,9 @@ void ServerEnvironment::step(float dtime)
// Step object
v3f last_position = obj->getBasePosition();
obj->step(dtime, send_recommended);
if(last_position != obj->getBasePosition()) {
m_ao_manager.invalidateCachedObjectID(obj->getId(), last_position);
v3f new_position = obj->getBasePosition();
if(last_position != new_position) {
m_ao_manager.updateCachedObjectID(obj->getId(), last_position, new_position);
}
// Read messages from object