Skip to content

Commit

Permalink
完成prof pt和prof chunk
Browse files Browse the repository at this point in the history
  • Loading branch information
xiaohengying committed Feb 13, 2022
1 parent e8e7d48 commit 227dcf0
Show file tree
Hide file tree
Showing 8 changed files with 198 additions and 91 deletions.
8 changes: 8 additions & 0 deletions api/block/BlockSource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@
#include "BlockSource.h"

#include "Block.h"
#include "graphics/BlockPos.h"
#include "lib/SymHook.h"
#include "lib/mod.h"
#include "world/Biome.h"

namespace trapdoor {
using namespace SymHook;

Expand Down Expand Up @@ -44,6 +46,12 @@ namespace trapdoor {
return SYM_CALL(Biome * (*)(BlockSource *, const BlockPos *),
BlockSource_getBiome_967864de, this, pos);
}

trapdoor::BlockPos2 LevelChunk::getPosition() {
auto res = *SYM_CALL(trapdoor::BlockPos2 * (*)(LevelChunk *),
LevelChunk_getPosition_5b2499b2, this);
return res;
}
} // namespace trapdoor
// using namespace SymHook;
// THook(trapdoor::Block *, BlockSource_getBlock_b39e5e5d,
Expand Down
9 changes: 9 additions & 0 deletions api/block/BlockSource.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ namespace trapdoor {

class BlockPos;

class BlockPos2;

class BlockSource {
public:
//获取某个位置的方块对象
Expand Down Expand Up @@ -42,6 +44,13 @@ namespace trapdoor {
// LevelChunk *getLevelChunk(const ChunkPos &chunkPos);
};

struct LevelChunk {
// //[24]?getPosition@LevelChunk@@QEBAAEBVChunkPos@@XZ;
// public: class ChunkPos const & __ptr64 __cdecl
// LevelChunk::getPosition(void)const __ptr64
BlockPos2 getPosition();
};

} // namespace trapdoor
typedef trapdoor::BlockSource BlockSource;
#endif // TRAPDOOR_BLOCKSOURCE_H
Binary file modified api/lib/SymHook.h
Binary file not shown.
46 changes: 32 additions & 14 deletions mod/tick/GameTick.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ namespace mod::tick {
}
}

void profileWorld(trapdoor::Actor *player, int round) {
void profileWorld(trapdoor::Actor *player, int round, ProfileType t) {
if (gameProfiler.inProfiling) {
trapdoor::warning(player, LANG("prof.error"));
return;
Expand All @@ -140,6 +140,7 @@ namespace mod::tick {
}
L_DEBUG("begin profiling");
broadcastMsg(LANG("prof.start"));
gameProfiler.profileType = t;
gameProfiler.inProfiling = true;
gameProfiler.totalRound = round;
gameProfiler.currentRound = gameProfiler.totalRound;
Expand Down Expand Up @@ -217,12 +218,26 @@ namespace mod::tick {
}

void registerProfileCommand(CommandManager &commandManager) {
commandManager.registerCmd("prof", "command.prof.desc")
commandManager
.registerCmd("prof", "command.prof.desc")
//自定义时常的基本测量
->then(ARG("c", "command.prof.c.desc", INT,
{ tick::profileWorld(player, holder->getInt()); }))
{
tick::profileWorld(player, holder->getInt(),
ProfileType::Normal);
}))
//实体分析
->then(ARG("actor", "command.prof.actor.desc", NONE,
{ tick::profileEntities(player); }))
->EXE({ tick::profileWorld(player, 100); });
//区块卡顿分析
->then(ARG("chunk", "command.prof.chunk.desc", NONE,
{ tick::profileWorld(player, 10, ProfileType::Chunk); }))
//计划可读长度分析
->then(ARG(
"pt", "command.prof.pt.desc", NONE,
{ tick::profileWorld(player, 10, ProfileType::PendingTick); }))
//默认基本分析(100gt)
->EXE({ tick::profileWorld(player, 100, ProfileType::Normal); });
commandManager.registerCmd("mspt", "command.mspt.desc")->EXE({
tick::mspt();
});
Expand Down Expand Up @@ -330,14 +345,14 @@ THook(void, Dimension_tick_39d89862, void *dim) {
}
}
// LevelChunk::tick
THook(void, LevelChunk_tick_9d729ccd, void *levelChunk,
THook(void, LevelChunk_tick_9d729ccd, trapdoor::LevelChunk *levelChunk,
trapdoor::BlockSource *blockSource, size_t *tick) {
if (mod::tick::gameProfiler.inProfiling) {
auto p = levelChunk->getPosition();
TIMER_START
original(levelChunk, blockSource, tick);
TIMER_END
mod::tick::gameProfiler.chunkTickTime += timeReslut;
mod::tick::gameProfiler.tickChunkNum++;
mod::tick::gameProfiler.chunkStat.counter[p] += timeReslut;
} else {
original(levelChunk, blockSource, tick);
}
Expand All @@ -350,7 +365,7 @@ THook(void, LevelChunk_tickBlocks_66280c26, void *levelChunk, void *blockSource,
TIMER_START
original(levelChunk, blockSource, a3, a4);
TIMER_END
mod::tick::gameProfiler.chunkRandomTickTime += timeReslut;
mod::tick::gameProfiler.chunkStat.randomTick += timeReslut;
} else {
original(levelChunk, blockSource, a3, a4);
}
Expand All @@ -363,7 +378,7 @@ THook(void, LevelChunk_tickBlockEntities_41f9b2ca, void *levelChunk,
TIMER_START
original(levelChunk, blockSource);
TIMER_END
mod::tick::gameProfiler.chunkBlockEntityTickTime += timeReslut;
mod::tick::gameProfiler.chunkStat.blockEntities += timeReslut;
} else {
original(levelChunk, blockSource);
}
Expand All @@ -373,6 +388,8 @@ THook(void, LevelChunk_tickBlockEntities_41f9b2ca, void *levelChunk,
THook(void, BlockTickingQueue_tickPendingTicks_e4625213,
trapdoor::BlockTickingQueue *queue, trapdoor::BlockSource *source,
uint64_t until, int max, bool instalTick) {
//上限调整为无限
// max = INT32_MAX;
// if (queue->next.queue.size() != 0 && flag) {
// // printf("Tick = %llu queue size is (%zd,%zu)\n",
// queue->currentTick,
Expand All @@ -395,8 +412,7 @@ THook(void, BlockTickingQueue_tickPendingTicks_e4625213,
}
original(queue, source, until, max, instalTick);
TIMER_END
mod::tick::gameProfiler.chunkPendingTickTime += timeReslut;

mod::tick::gameProfiler.chunkStat.pendingTick += timeReslut;
} else {
original(queue, source, until, max, instalTick);
}
Expand All @@ -408,7 +424,8 @@ THook(void, Dimension_tickRedstone_c8a7e6e5, void *dim) {
TIMER_START
original(dim);
TIMER_END
mod::tick::gameProfiler.redstoneTickTime += timeReslut;
// mod::tick::gameProfiler.redstoneTickTime += timeReslut;
mod::tick::gameProfiler.redstonStat.signals += timeReslut;
} else {
original(dim);
}
Expand Down Expand Up @@ -454,7 +471,8 @@ THook(void, CircuitSceneGraph_processPendingAdds_9d2954e5, void *graph) {
TIMER_START
original(graph);
TIMER_END
mod::tick::gameProfiler.redstonePendingAddTime += timeReslut;
mod::tick::gameProfiler.redstonStat.pendingAdd += timeReslut;

} else {
original(graph);
}
Expand All @@ -466,7 +484,7 @@ THook(void, CircuitSceneGraph_removeComponent_1f06081d, void *graph, void *bs) {
TIMER_START
original(graph, bs);
TIMER_END
mod::tick::gameProfiler.redstonePendingRemoveTime += timeReslut;
mod::tick::gameProfiler.redstonStat.pendingRemove += timeReslut;
} else {
original(graph, bs);
}
Expand Down
2 changes: 1 addition & 1 deletion mod/tick/GameTick.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ namespace mod::tick {

void slowTick(size_t slowSpeed);

void profileWorld(trapdoor::Actor *player, int round = 0);
void profileWorld(trapdoor::Actor *player, int round, ProfileType type);

void profileEntities(trapdoor::Actor *player);

Expand Down
137 changes: 91 additions & 46 deletions mod/tick/SimpleProfiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,92 @@ namespace mod {
// levelEntitySystemTickTime = 0; //实体系统更新 O

void SimpleProfiler::print() const {
if (this->profileType == ProfileType::Normal) {
this->printBasics();
} else if (this->profileType == ProfileType::Chunk) {
this->printChunks();
} else if (this->profileType == ProfileType::PendingTick) {
this->printPendingTicks();
}
}

void SimpleProfiler::printChunks() const {
microsecond_t chunkTickTime = 0;
auto rounds = static_cast<float>(this->totalRound * 1000);
std::vector<std::pair<trapdoor::BlockPos2, microsecond_t>> data;
for (auto &kv : this->chunkStat.counter) {
data.push_back(kv);
chunkTickTime += kv.second;
}
std::sort(data.begin(), data.end(),
[](const std::pair<trapdoor::BlockPos2, microsecond_t> &p1,
const std::pair<trapdoor::BlockPos2, microsecond_t> &p2) {
return p1.second > p2.second;
});
int count = 10;
if (count > data.size()) {
count = data.size();
}
trapdoor::MessageBuilder builder;

builder.textF("%zu chunks ticked, %.3f ms total\n",
this->chunkStat.counter.size(), chunkTickTime / rounds);
for (int i = 0; i < count; i++) {
auto &d = data[i];
builder.sText(" - ", trapdoor::MSG_COLOR::GRAY);
builder
.sTextF(trapdoor::MSG_COLOR::WHITE, "[%d,%d] ",
d.first.x * 16 + 8, d.first.z * 16 + 8)
.sTextF(trapdoor::MSG_COLOR::GREEN, "%.3f", d.second / rounds)
.text("ms\n");
}

builder.broadcast();
}

void SimpleProfiler::printPendingTicks() const {
int totalPtLen = 0;

std::vector<std::pair<trapdoor::BlockPos2, size_t>> data;
for (auto &kv : this->ptCounter) {
data.push_back(kv);
totalPtLen += kv.second;
}

std::sort(data.begin(), data.end(),
[](const std::pair<trapdoor::BlockPos2, microsecond_t> &p1,
const std::pair<trapdoor::BlockPos2, microsecond_t> &p2) {
return p1.second > p2.second;
});
int count = 10;
if (count > data.size()) {
count = data.size();
}
trapdoor::MessageBuilder builder;
builder.textF(
"%zu chunks ticked,here are the cached pending tick size\n",
this->chunkStat.counter.size());
for (int i = 0; i < count; i++) {
auto &d = data[i];
builder.sText(" - ", trapdoor::MSG_COLOR::GRAY);
builder.sTextF(trapdoor::MSG_COLOR::WHITE, "[%d,%d] ",
d.first.x * 16 + 8, d.first.z * 16 + 8);
int num = d.second / this->totalRound;
auto color = num >= 100 ? trapdoor::MSG_COLOR::RED
: trapdoor::MSG_COLOR::GREEN;
builder.sTextF(color, "%d\n", d.second / this->totalRound);
}
builder.broadcast();
}

void SimpleProfiler::printBasics() const {
auto rounds = static_cast<float>(this->totalRound * 1000);
float mspt = serverLevelTickTime / rounds;
int tps = static_cast<int>(1000.0 / mspt);
if (tps > 20) tps = 20;
trapdoor::MessageBuilder builder;
auto totalRedstoneTickTime =
static_cast<float>(redstoneTickTime + redstonePendingUpdateTime +
redstonePendingRemoveTime) /
rounds;
static_cast<float>(this->redstonStat.total()) / rounds;

auto firstLineColor =
trapdoor::MSG_COLOR::WHITE || trapdoor::MSG_COLOR::BOLD;
Expand All @@ -70,67 +147,35 @@ namespace mod {
}
color |= trapdoor::MSG_COLOR::BOLD;

size_t counter = 0;
size_t max = 0;
//根据统计的计划刻队列的长度来打印对应信息
bool existPtOverflow = false;
for (auto &kv : this->ptCounter) {
counter += kv.second;
if (max < kv.second) {
max = kv.second;
}
if (kv.second >= 100) {
existPtOverflow = true;
}
microsecond_t chunkTickTime = 0;
for (auto &data : this->chunkStat.counter) {
chunkTickTime += data.second;
}

auto ptNum =
static_cast<float>(counter * this->totalRound) / tickChunkNum;

builder.sTextF(color, "%.3fms", mspt)
.sTextF(firstLineColor, " TPS: ")
.sTextF(color, "%d", tps)
.sTextF(firstLineColor, " CHUNKS: %d(pt: %.2f,%u)\n",
tickChunkNum / this->totalRound, ptNum, max);
.sTextF(firstLineColor, " CHUNKS: %d\n", chunkStat.counter.size());
addShowItem(builder, " - ", "Redstone", totalRedstoneTickTime, mspt);
addShowItem(builder, " - ", "SignalUpdate",
redstoneTickTime / rounds, mspt);
redstonStat.signals / rounds, mspt);
builder.sText(" - ", trapdoor::MSG_COLOR::GRAY)
.text("PendingUpdate: Invalid\n");
addShowItem(builder, " - ", "PendingRemove",
redstonePendingRemoveTime / rounds, mspt);
redstonStat.pendingRemove / rounds, mspt);

addShowItem(builder, " - ", "EntitySystem",
levelEntitySystemTickTime / rounds, mspt);
addShowItem(builder, " - ", "Chunk (un)load & village",
dimensionTickTime / rounds, mspt);

addShowItem(builder, " - ", "ChunkTick", chunkTickTime / rounds, mspt);
addShowItem(builder, " - ", "BlockEntities",
chunkBlockEntityTickTime / rounds, mspt);
chunkStat.blockEntities / rounds, mspt);
addShowItem(builder, " - ", "RandomTick",
chunkRandomTickTime / rounds, mspt);
chunkStat.randomTick / rounds, mspt);
addShowItem(builder, " - ", "PendingTick",
chunkPendingTickTime / rounds, mspt);

if (existPtOverflow) {
builder.text("Here are pending tick overflow chunks:\n");
for (auto &kv : this->ptCounter) {
if (kv.second >= 100) {
builder.sTextF(trapdoor::MSG_COLOR::RED, "[%d,%d] ",
kv.first.x * 16 + 8, kv.first.z * 16 + 8);
}
}
}
chunkStat.pendingTick / rounds, mspt);
builder.broadcast();
// .textF(" - Chunk tick: %.3fms (%d)\n", chunkTickTime / rounds,
// tickChunkNum / totalRound)
// .textF(" - Block entity: %.3fms\n",
// chunkBlockEntityTickTime / rounds)
// .textF(" - Random tick: %.3fms\n", chunkRandomTickTime /
// rounds)
// .textF(" - Pending tick: %.3f/%.3fms\n",
// chunkRandomPendingTickTime / rounds,
// chunkPendingTickTime / rounds)
// .text(" - Entity tick: may be the rest")
// .broadcast();
}
} // namespace mod
Loading

0 comments on commit 227dcf0

Please sign in to comment.