尝试同步
This commit is contained in:
13
test.cpp
13
test.cpp
@@ -27,6 +27,7 @@ vector<vector<double>> matrixMultiply(const vector<vector<double>>& A, const vec
|
|||||||
for (size_t j = 0; j < m; j++) {
|
for (size_t j = 0; j < m; j++) {
|
||||||
for (size_t k = 0; k < p; k++) {
|
for (size_t k = 0; k < p; k++) {
|
||||||
result[i][j] += A[i][k] * B[k][j];
|
result[i][j] += A[i][k] * B[k][j];
|
||||||
|
TracyPlot("matrixMultiply", result[i][j]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -46,6 +47,7 @@ vector<vector<double>> generateRandomMatrix(size_t rows, size_t cols) {
|
|||||||
for (size_t i = 0; i < rows; i++) {
|
for (size_t i = 0; i < rows; i++) {
|
||||||
for (size_t j = 0; j < cols; j++) {
|
for (size_t j = 0; j < cols; j++) {
|
||||||
matrix[i][j] = dis(gen);
|
matrix[i][j] = dis(gen);
|
||||||
|
TracyPlot("generateRandomMatrix", matrix[i][j]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,7 +70,9 @@ void quickSort(vector<int>& arr, int low, int high) {
|
|||||||
}
|
}
|
||||||
swap(arr[i + 1], arr[high]);
|
swap(arr[i + 1], arr[high]);
|
||||||
int pi = i + 1;
|
int pi = i + 1;
|
||||||
|
|
||||||
|
TracyPlot("quickSort.low", (int64_t)low);
|
||||||
|
TracyPlot("quickSort.high", (int64_t)high);
|
||||||
quickSort(arr, low, pi - 1);
|
quickSort(arr, low, pi - 1);
|
||||||
quickSort(arr, pi + 1, high);
|
quickSort(arr, pi + 1, high);
|
||||||
}
|
}
|
||||||
@@ -88,6 +92,7 @@ vector<int> sieveOfEratosthenes(int n) {
|
|||||||
primes.push_back(i);
|
primes.push_back(i);
|
||||||
for (int j = i * 2; j <= n; j += i) {
|
for (int j = i * 2; j <= n; j += i) {
|
||||||
isPrime[j] = false;
|
isPrime[j] = false;
|
||||||
|
TracyPlot("sieveOfEratosthenes", (isPrime[j] ? 1.0 : 0.0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -108,7 +113,8 @@ double calculatePi(int iterations) {
|
|||||||
for (int i = 0; i < iterations; i++) {
|
for (int i = 0; i < iterations; i++) {
|
||||||
double x = dis(gen);
|
double x = dis(gen);
|
||||||
double y = dis(gen);
|
double y = dis(gen);
|
||||||
|
|
||||||
|
TracyPlot("calculatePi", (x * x + y * y));
|
||||||
if (x * x + y * y <= 1.0) {
|
if (x * x + y * y <= 1.0) {
|
||||||
insideCircle++;
|
insideCircle++;
|
||||||
}
|
}
|
||||||
@@ -120,6 +126,7 @@ double calculatePi(int iterations) {
|
|||||||
// 斐波那契数列(递归)
|
// 斐波那契数列(递归)
|
||||||
long long fibonacci(int n) {
|
long long fibonacci(int n) {
|
||||||
ZoneScoped;
|
ZoneScoped;
|
||||||
|
TracyPlot("fibonacci", (int64_t)n);
|
||||||
|
|
||||||
if (n <= 1) return n;
|
if (n <= 1) return n;
|
||||||
return fibonacci(n - 1) + fibonacci(n - 2);
|
return fibonacci(n - 1) + fibonacci(n - 2);
|
||||||
@@ -149,6 +156,7 @@ double dotProduct(const vector<double>& a, const vector<double>& b) {
|
|||||||
double result = 0.0;
|
double result = 0.0;
|
||||||
for (size_t i = 0; i < a.size(); i++) {
|
for (size_t i = 0; i < a.size(); i++) {
|
||||||
result += a[i] * b[i];
|
result += a[i] * b[i];
|
||||||
|
TracyPlot("dotProduct", result);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@@ -161,6 +169,7 @@ void complexMathOperations(int iterations) {
|
|||||||
double sum = 0.0;
|
double sum = 0.0;
|
||||||
for (int i = 1; i <= iterations; i++) {
|
for (int i = 1; i <= iterations; i++) {
|
||||||
sum += sin(i) * cos(i) + tan(i / 100.0) + sqrt(i) + log(i);
|
sum += sin(i) * cos(i) + tan(i / 100.0) + sqrt(i) + log(i);
|
||||||
|
TracyPlot("complexMathOperations", sum);
|
||||||
}
|
}
|
||||||
|
|
||||||
cout << "复杂数学计算结果: " << sum << endl;
|
cout << "复杂数学计算结果: " << sum << endl;
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ option(IS_TRACY_ON_DEMAND "Tracy 按需分析模式" ON)
|
|||||||
option(IS_TRACY_NO_EXIT "Tracy 不在退出时断开连接" OFF)
|
option(IS_TRACY_NO_EXIT "Tracy 不在退出时断开连接" OFF)
|
||||||
option(IS_TRACY_NO_BROADCAST "Tracy 不广播发现消息" OFF)
|
option(IS_TRACY_NO_BROADCAST "Tracy 不广播发现消息" OFF)
|
||||||
option(IS_TRACY_ONLY_LOCALHOST "Tracy 仅允许本地连接" OFF)
|
option(IS_TRACY_ONLY_LOCALHOST "Tracy 仅允许本地连接" OFF)
|
||||||
option(IS_ADVANCED_ZONE_MANAGEMENT "启用Tracy管理器类" ON)
|
|
||||||
|
|
||||||
# ============================================
|
# ============================================
|
||||||
# Tracy 配置
|
# Tracy 配置
|
||||||
@@ -46,10 +45,6 @@ if(IS_TRACY_ONLY_LOCALHOST)
|
|||||||
add_definitions(-DTRACY_ONLY_LOCALHOST)
|
add_definitions(-DTRACY_ONLY_LOCALHOST)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(IS_ADVANCED_ZONE_MANAGEMENT)
|
|
||||||
add_definitions(-DADVANCED_ZONE_MANAGEMENT)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# ============================================
|
# ============================================
|
||||||
# Tracy 路径配置
|
# Tracy 路径配置
|
||||||
# ============================================
|
# ============================================
|
||||||
|
|||||||
@@ -15,13 +15,8 @@
|
|||||||
#include "tracy/Tracy.hpp"
|
#include "tracy/Tracy.hpp"
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <map>
|
||||||
#ifdef ADVANCED_ZONE_MANAGEMENT
|
|
||||||
#include <unordered_map>
|
|
||||||
#include <stack>
|
#include <stack>
|
||||||
#include <mutex>
|
|
||||||
#include <thread>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Platform specific export definition
|
// Platform specific export definition
|
||||||
#if defined(_WIN32) || defined(_WIN64)
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
@@ -32,22 +27,10 @@
|
|||||||
#define UNITY_PLUGIN_EXPORT
|
#define UNITY_PLUGIN_EXPORT
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Simple Zone Manager for basic Zone tracking
|
std::map<std::string, tracy::SourceLocationData> sourceLocationCache;
|
||||||
#ifndef ADVANCED_ZONE_MANAGEMENT
|
std::map<std::string, std::string> zoneFunctionNameCache;
|
||||||
namespace {
|
std::map<std::string, std::string> zoneFilePathCache;
|
||||||
struct SimpleZone {
|
std::map<std::string, std::stack<tracy::ScopedZone*>> zoneStackCache;
|
||||||
const char* name;
|
|
||||||
int64_t startTime;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ThreadZones {
|
|
||||||
std::stack<SimpleZone> zones;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::unordered_map<std::thread::id, ThreadZones> g_threadZones;
|
|
||||||
std::mutex g_zonesMutex;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// C export functions (Unity requires C linkage)
|
// C export functions (Unity requires C linkage)
|
||||||
extern "C"
|
extern "C"
|
||||||
@@ -67,10 +50,7 @@ extern "C"
|
|||||||
*/
|
*/
|
||||||
UNITY_PLUGIN_EXPORT void TracyShutdown()
|
UNITY_PLUGIN_EXPORT void TracyShutdown()
|
||||||
{
|
{
|
||||||
#ifndef ADVANCED_ZONE_MANAGEMENT
|
|
||||||
std::lock_guard<std::mutex> lock(g_zonesMutex);
|
|
||||||
g_threadZones.clear();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -118,51 +98,6 @@ extern "C"
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Begin a named Zone
|
|
||||||
* Unity C# call: [DllImport] private static extern void TracyZoneBegin(string name);
|
|
||||||
*
|
|
||||||
* Note: This is a simplified implementation. For production use, consider using
|
|
||||||
* ADVANCED_ZONE_MANAGEMENT or a different Zone management approach.
|
|
||||||
*/
|
|
||||||
UNITY_PLUGIN_EXPORT void TracyZoneBegin(const char* name)
|
|
||||||
{
|
|
||||||
#ifndef ADVANCED_ZONE_MANAGEMENT
|
|
||||||
if (name != nullptr)
|
|
||||||
{
|
|
||||||
std::lock_guard<std::mutex> lock(g_zonesMutex);
|
|
||||||
auto threadId = std::this_thread::get_id();
|
|
||||||
|
|
||||||
SimpleZone zone;
|
|
||||||
zone.name = name;
|
|
||||||
zone.startTime = tracy::GetTime();
|
|
||||||
|
|
||||||
g_threadZones[threadId].zones.push(zone);
|
|
||||||
|
|
||||||
// Send zone begin event to Tracy
|
|
||||||
TracyMessageL(name);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* End current Zone
|
|
||||||
* Unity C# call: [DllImport] private static extern void TracyZoneEnd();
|
|
||||||
*/
|
|
||||||
UNITY_PLUGIN_EXPORT void TracyZoneEnd()
|
|
||||||
{
|
|
||||||
#ifndef ADVANCED_ZONE_MANAGEMENT
|
|
||||||
std::lock_guard<std::mutex> lock(g_zonesMutex);
|
|
||||||
auto threadId = std::this_thread::get_id();
|
|
||||||
auto it = g_threadZones.find(threadId);
|
|
||||||
|
|
||||||
if (it != g_threadZones.end() && !it->second.zones.empty())
|
|
||||||
{
|
|
||||||
it->second.zones.pop();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unity plugin lifecycle function - called on load
|
* Unity plugin lifecycle function - called on load
|
||||||
*/
|
*/
|
||||||
@@ -180,117 +115,33 @@ extern "C"
|
|||||||
TracyShutdown();
|
TracyShutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // extern "C"
|
UNITY_PLUGIN_EXPORT void TracyZoneScopedBegin(
|
||||||
|
const char* name,
|
||||||
/*
|
const char* functionName,
|
||||||
* Advanced Implementation Example - Zone Management
|
const char* filePath,
|
||||||
*
|
int lineNumber
|
||||||
* Below is a more complete Zone management implementation example
|
)
|
||||||
* Can be extended as needed
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef ADVANCED_ZONE_MANAGEMENT
|
|
||||||
|
|
||||||
// Zone Manager (Thread-safe)
|
|
||||||
class ZoneManager
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
struct ThreadZones
|
|
||||||
{
|
{
|
||||||
std::stack<tracy::ScopedZone*> zones;
|
std::string nameStr(name);
|
||||||
};
|
auto iter = sourceLocationCache.find(nameStr);
|
||||||
|
if (iter == sourceLocationCache.end())
|
||||||
std::unordered_map<std::thread::id, ThreadZones> threadZones;
|
|
||||||
std::mutex mutex;
|
|
||||||
|
|
||||||
public:
|
|
||||||
void BeginZone(const char* name, const char* function, const char* file, uint32_t line)
|
|
||||||
{
|
|
||||||
std::lock_guard<std::mutex> lock(mutex);
|
|
||||||
|
|
||||||
auto threadId = std::this_thread::get_id();
|
|
||||||
auto& zones = threadZones[threadId].zones;
|
|
||||||
|
|
||||||
// Create source location info
|
|
||||||
static const tracy::SourceLocationData loc{name, function, file, line, 0};
|
|
||||||
|
|
||||||
// Create Zone (note: must be heap allocated)
|
|
||||||
auto* zone = new tracy::ScopedZone(&loc, true);
|
|
||||||
zones.push(zone);
|
|
||||||
}
|
|
||||||
|
|
||||||
void EndZone()
|
|
||||||
{
|
|
||||||
std::lock_guard<std::mutex> lock(mutex);
|
|
||||||
|
|
||||||
auto threadId = std::this_thread::get_id();
|
|
||||||
auto it = threadZones.find(threadId);
|
|
||||||
|
|
||||||
if (it != threadZones.end() && !it->second.zones.empty())
|
|
||||||
{
|
{
|
||||||
auto* zone = it->second.zones.top();
|
zoneFunctionNameCache[nameStr] = functionName;
|
||||||
it->second.zones.pop();
|
zoneFilePathCache[nameStr] = filePath;
|
||||||
delete zone;
|
iter = sourceLocationCache.insert(sourceLocationCache.end(), std::make_pair(nameStr, tracy::SourceLocationData{}));
|
||||||
|
iter->second.name = iter->first.c_str();
|
||||||
|
iter->second.function = zoneFunctionNameCache[nameStr].c_str();
|
||||||
|
iter->second.file = zoneFilePathCache[nameStr].c_str();
|
||||||
|
iter->second.line = static_cast<uint32_t>(lineNumber);
|
||||||
|
iter->second.color = 0;
|
||||||
}
|
}
|
||||||
|
zoneStackCache[nameStr].push(new tracy::ScopedZone(&iter->second, 0, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClearThread()
|
UNITY_PLUGIN_EXPORT void TracyZoneScopedEnd(const char* name)
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(mutex);
|
delete zoneStackCache[name].top();
|
||||||
|
zoneStackCache[name].pop();
|
||||||
auto threadId = std::this_thread::get_id();
|
|
||||||
auto it = threadZones.find(threadId);
|
|
||||||
|
|
||||||
if (it != threadZones.end())
|
|
||||||
{
|
|
||||||
// Clean up all unfinished Zones
|
|
||||||
while (!it->second.zones.empty())
|
|
||||||
{
|
|
||||||
delete it->second.zones.top();
|
|
||||||
it->second.zones.pop();
|
|
||||||
}
|
|
||||||
threadZones.erase(it);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
// Global Zone Manager instance
|
|
||||||
static ZoneManager g_zoneManager;
|
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
|
|
||||||
UNITY_PLUGIN_EXPORT void TracyZoneBeginAdvanced(const char* name, const char* function, const char* file, int line)
|
|
||||||
{
|
|
||||||
g_zoneManager.BeginZone(name, function, file, static_cast<uint32_t>(line));
|
|
||||||
}
|
|
||||||
|
|
||||||
UNITY_PLUGIN_EXPORT void TracyZoneEndAdvanced()
|
|
||||||
{
|
|
||||||
g_zoneManager.EndZone();
|
|
||||||
}
|
|
||||||
|
|
||||||
UNITY_PLUGIN_EXPORT void TracyClearThreadZones()
|
|
||||||
{
|
|
||||||
g_zoneManager.ClearThread();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
|
|
||||||
#endif // ADVANCED_ZONE_MANAGEMENT
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Build and Deployment Instructions:
|
|
||||||
*
|
|
||||||
* Use CMake for all platforms (see CMakeLists.txt)
|
|
||||||
*
|
|
||||||
* Quick build:
|
|
||||||
* 1. mkdir build && cd build
|
|
||||||
* 2. cmake .. -DTRACY_ROOT="/path/to/tracy"
|
|
||||||
* 3. cmake --build . --config Release
|
|
||||||
*
|
|
||||||
* Deploy to Unity:
|
|
||||||
* - Copy compiled library to Unity project Assets/Plugins/ directory
|
|
||||||
* - Place in appropriate subdirectory based on platform
|
|
||||||
* - Configure Plugin Import Settings to match target platform
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,396 +0,0 @@
|
|||||||
using UnityEngine;
|
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using TracyProfiler;
|
|
||||||
|
|
||||||
namespace TracyProfiler.Examples
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Tracy 使用示例
|
|
||||||
/// 展示如何在不同场景下使用 Tracy 性能分析
|
|
||||||
/// </summary>
|
|
||||||
public class TracyExamples : MonoBehaviour
|
|
||||||
{
|
|
||||||
[Header("测试参数")]
|
|
||||||
[SerializeField] private int heavyComputationIterations = 10000;
|
|
||||||
[SerializeField] private int objectPoolSize = 100;
|
|
||||||
[SerializeField] private bool runContinuousTest = false;
|
|
||||||
|
|
||||||
private List<GameObject> objectPool = new List<GameObject>();
|
|
||||||
|
|
||||||
private void Start()
|
|
||||||
{
|
|
||||||
Tracy.Message("TracyExamples - 示例场景启动");
|
|
||||||
InitializeObjectPool();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Update()
|
|
||||||
{
|
|
||||||
// 示例 1: 追踪整个 Update 方法
|
|
||||||
using (Tracy.Zone("TracyExamples.Update"))
|
|
||||||
{
|
|
||||||
// 示例 2: 追踪输入处理
|
|
||||||
HandleInput();
|
|
||||||
|
|
||||||
// 示例 3: 追踪游戏逻辑
|
|
||||||
if (runContinuousTest)
|
|
||||||
{
|
|
||||||
UpdateGameLogic();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 示例 4: 绘制自定义数据
|
|
||||||
PlotCustomData();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#region 示例 1: 基础 Zone 使用
|
|
||||||
|
|
||||||
private void HandleInput()
|
|
||||||
{
|
|
||||||
using (Tracy.Zone("Handle Input"))
|
|
||||||
{
|
|
||||||
if (Input.GetKeyDown(KeyCode.Space))
|
|
||||||
{
|
|
||||||
Tracy.Message("用户按下空格键");
|
|
||||||
PerformHeavyComputation();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Input.GetKeyDown(KeyCode.R))
|
|
||||||
{
|
|
||||||
Tracy.Message("用户按下 R 键 - 重置对象池");
|
|
||||||
ResetObjectPool();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Input.GetKeyDown(KeyCode.T))
|
|
||||||
{
|
|
||||||
Tracy.Message("用户按下 T 键 - 运行测试");
|
|
||||||
StartCoroutine(RunPerformanceTest());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region 示例 2: 计算密集型操作追踪
|
|
||||||
|
|
||||||
private void UpdateGameLogic()
|
|
||||||
{
|
|
||||||
using (Tracy.Zone("Update Game Logic"))
|
|
||||||
{
|
|
||||||
// 模拟一些游戏逻辑
|
|
||||||
ProcessAI();
|
|
||||||
UpdatePhysics();
|
|
||||||
CheckCollisions();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ProcessAI()
|
|
||||||
{
|
|
||||||
using (Tracy.Zone("Process AI"))
|
|
||||||
{
|
|
||||||
// 模拟 AI 计算
|
|
||||||
float sum = 0;
|
|
||||||
for (int i = 0; i < 1000; i++)
|
|
||||||
{
|
|
||||||
sum += Mathf.Sin(i) * Mathf.Cos(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
Tracy.Plot("AI Computation Result", sum);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdatePhysics()
|
|
||||||
{
|
|
||||||
using (Tracy.Zone("Update Physics"))
|
|
||||||
{
|
|
||||||
// 模拟物理更新
|
|
||||||
foreach (var obj in objectPool)
|
|
||||||
{
|
|
||||||
if (obj.activeInHierarchy)
|
|
||||||
{
|
|
||||||
// 简单的物理模拟
|
|
||||||
obj.transform.position += Vector3.down * Time.deltaTime;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void CheckCollisions()
|
|
||||||
{
|
|
||||||
using (Tracy.Zone("Check Collisions"))
|
|
||||||
{
|
|
||||||
// 模拟碰撞检测
|
|
||||||
int activeObjects = 0;
|
|
||||||
foreach (var obj in objectPool)
|
|
||||||
{
|
|
||||||
if (obj.activeInHierarchy)
|
|
||||||
{
|
|
||||||
activeObjects++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Tracy.Plot("Active Objects", activeObjects);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region 示例 3: 重度计算测试
|
|
||||||
|
|
||||||
[ContextMenu("执行重度计算")]
|
|
||||||
public void PerformHeavyComputation()
|
|
||||||
{
|
|
||||||
using (Tracy.Zone("Heavy Computation"))
|
|
||||||
{
|
|
||||||
Tracy.Message($"开始重度计算 ({heavyComputationIterations} 次迭代)");
|
|
||||||
|
|
||||||
// 矩阵运算
|
|
||||||
using (Tracy.Zone("Matrix Operations"))
|
|
||||||
{
|
|
||||||
Matrix4x4 result = Matrix4x4.identity;
|
|
||||||
for (int i = 0; i < heavyComputationIterations; i++)
|
|
||||||
{
|
|
||||||
Matrix4x4 temp = Matrix4x4.TRS(
|
|
||||||
Random.insideUnitSphere,
|
|
||||||
Random.rotation,
|
|
||||||
Vector3.one
|
|
||||||
);
|
|
||||||
result = result * temp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 数学运算
|
|
||||||
using (Tracy.Zone("Math Operations"))
|
|
||||||
{
|
|
||||||
double sum = 0;
|
|
||||||
for (int i = 0; i < heavyComputationIterations; i++)
|
|
||||||
{
|
|
||||||
sum += System.Math.Sqrt(i) * System.Math.Sin(i) * System.Math.Cos(i);
|
|
||||||
}
|
|
||||||
Tracy.Plot("Math Result", sum);
|
|
||||||
}
|
|
||||||
|
|
||||||
Tracy.Message("重度计算完成");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region 示例 4: 对象池管理
|
|
||||||
|
|
||||||
private void InitializeObjectPool()
|
|
||||||
{
|
|
||||||
using (Tracy.Zone("Initialize Object Pool"))
|
|
||||||
{
|
|
||||||
Tracy.Message($"初始化对象池 (大小: {objectPoolSize})");
|
|
||||||
|
|
||||||
for (int i = 0; i < objectPoolSize; i++)
|
|
||||||
{
|
|
||||||
GameObject obj = GameObject.CreatePrimitive(PrimitiveType.Cube);
|
|
||||||
obj.name = $"PoolObject_{i}";
|
|
||||||
obj.transform.position = Random.insideUnitSphere * 10f;
|
|
||||||
obj.SetActive(false);
|
|
||||||
objectPool.Add(obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
Tracy.Plot("Object Pool Size", objectPoolSize);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[ContextMenu("重置对象池")]
|
|
||||||
public void ResetObjectPool()
|
|
||||||
{
|
|
||||||
using (Tracy.Zone("Reset Object Pool"))
|
|
||||||
{
|
|
||||||
foreach (var obj in objectPool)
|
|
||||||
{
|
|
||||||
obj.transform.position = Random.insideUnitSphere * 10f;
|
|
||||||
obj.SetActive(Random.value > 0.5f);
|
|
||||||
}
|
|
||||||
|
|
||||||
Tracy.Message("对象池已重置");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region 示例 5: 协程性能追踪
|
|
||||||
|
|
||||||
[ContextMenu("运行性能测试")]
|
|
||||||
public void StartPerformanceTest()
|
|
||||||
{
|
|
||||||
StartCoroutine(RunPerformanceTest());
|
|
||||||
}
|
|
||||||
|
|
||||||
private IEnumerator RunPerformanceTest()
|
|
||||||
{
|
|
||||||
Tracy.Message("=== 性能测试开始 ===");
|
|
||||||
|
|
||||||
// 测试 1: 快速操作
|
|
||||||
using (Tracy.Zone("Test: Fast Operations"))
|
|
||||||
{
|
|
||||||
for (int i = 0; i < 100; i++)
|
|
||||||
{
|
|
||||||
float temp = Mathf.Sin(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
yield return null;
|
|
||||||
|
|
||||||
// 测试 2: 中等操作
|
|
||||||
using (Tracy.Zone("Test: Medium Operations"))
|
|
||||||
{
|
|
||||||
for (int i = 0; i < 1000; i++)
|
|
||||||
{
|
|
||||||
Vector3 temp = Random.insideUnitSphere;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
yield return new WaitForSeconds(0.1f);
|
|
||||||
|
|
||||||
// 测试 3: 慢速操作
|
|
||||||
using (Tracy.Zone("Test: Slow Operations"))
|
|
||||||
{
|
|
||||||
for (int i = 0; i < objectPoolSize; i++)
|
|
||||||
{
|
|
||||||
objectPool[i].SetActive(true);
|
|
||||||
objectPool[i].transform.position = Random.insideUnitSphere * 20f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
yield return null;
|
|
||||||
|
|
||||||
Tracy.Message("=== 性能测试完成 ===");
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region 示例 6: 自定义数据绘制
|
|
||||||
|
|
||||||
private void PlotCustomData()
|
|
||||||
{
|
|
||||||
using (Tracy.Zone("Plot Custom Data"))
|
|
||||||
{
|
|
||||||
// 绘制内存使用
|
|
||||||
long memoryUsed = System.GC.GetTotalMemory(false);
|
|
||||||
Tracy.Plot("Custom Memory (MB)", memoryUsed / (1024.0 * 1024.0));
|
|
||||||
|
|
||||||
// 绘制对象计数
|
|
||||||
int activeCount = 0;
|
|
||||||
foreach (var obj in objectPool)
|
|
||||||
{
|
|
||||||
if (obj.activeInHierarchy) activeCount++;
|
|
||||||
}
|
|
||||||
Tracy.Plot("Active Pool Objects", activeCount);
|
|
||||||
|
|
||||||
// 绘制帧时间
|
|
||||||
Tracy.Plot("Custom Frame Time (ms)", Time.deltaTime * 1000f);
|
|
||||||
|
|
||||||
// 绘制时间戳
|
|
||||||
Tracy.Plot("Time Since Startup", Time.realtimeSinceStartup);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region 示例 7: 条件性能追踪
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 演示如何使用条件编译来控制 Tracy 的开销
|
|
||||||
/// </summary>
|
|
||||||
private void ConditionalProfiling()
|
|
||||||
{
|
|
||||||
#if TRACY_ENABLE
|
|
||||||
// 只有在定义了 TRACY_ENABLE 时才执行的代码
|
|
||||||
using (Tracy.Zone("Conditional Profiling"))
|
|
||||||
{
|
|
||||||
// 详细的性能追踪
|
|
||||||
DetailedPerformanceTracking();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
private void DetailedPerformanceTracking()
|
|
||||||
{
|
|
||||||
// 非常细粒度的性能追踪
|
|
||||||
for (int i = 0; i < 10; i++)
|
|
||||||
{
|
|
||||||
using (Tracy.Zone($"Iteration {i}"))
|
|
||||||
{
|
|
||||||
// 每次迭代的详细追踪
|
|
||||||
System.Threading.Thread.Sleep(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
private void OnDestroy()
|
|
||||||
{
|
|
||||||
// 清理对象池
|
|
||||||
using (Tracy.Zone("Cleanup Object Pool"))
|
|
||||||
{
|
|
||||||
foreach (var obj in objectPool)
|
|
||||||
{
|
|
||||||
if (obj != null)
|
|
||||||
{
|
|
||||||
Destroy(obj);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
objectPool.Clear();
|
|
||||||
|
|
||||||
Tracy.Message("TracyExamples - 场景清理完成");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if UNITY_EDITOR
|
|
||||||
[ContextMenu("切换连续测试")]
|
|
||||||
private void ToggleContinuousTest()
|
|
||||||
{
|
|
||||||
runContinuousTest = !runContinuousTest;
|
|
||||||
Tracy.Message($"连续测试: {(runContinuousTest ? "启用" : "禁用")}");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 演示如何在自定义类中使用 Tracy
|
|
||||||
/// </summary>
|
|
||||||
public class CustomSystem
|
|
||||||
{
|
|
||||||
private string systemName;
|
|
||||||
|
|
||||||
public CustomSystem(string name)
|
|
||||||
{
|
|
||||||
systemName = name;
|
|
||||||
Tracy.Message($"{systemName} - 系统创建");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Update()
|
|
||||||
{
|
|
||||||
using (Tracy.Zone($"{systemName}.Update"))
|
|
||||||
{
|
|
||||||
// 系统更新逻辑
|
|
||||||
ProcessData();
|
|
||||||
UpdateState();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ProcessData()
|
|
||||||
{
|
|
||||||
using (Tracy.Zone($"{systemName}.ProcessData"))
|
|
||||||
{
|
|
||||||
// 数据处理
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdateState()
|
|
||||||
{
|
|
||||||
using (Tracy.Zone($"{systemName}.UpdateState"))
|
|
||||||
{
|
|
||||||
// 状态更新
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace TracyProfiler
|
namespace TracyProfiler
|
||||||
@@ -37,10 +38,11 @@ namespace TracyProfiler
|
|||||||
private static extern void TracySetThreadName(string name);
|
private static extern void TracySetThreadName(string name);
|
||||||
|
|
||||||
[DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)]
|
[DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)]
|
||||||
private static extern void TracyZoneBegin(string name);
|
private static extern void TracyZoneScopedBegin(string name, string function = "", string file = "",
|
||||||
|
int line = 0);
|
||||||
|
|
||||||
[DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)]
|
[DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)]
|
||||||
private static extern void TracyZoneEnd();
|
private static extern void TracyZoneScopedEnd(string name);
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@@ -70,7 +72,7 @@ namespace TracyProfiler
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
#if TRACY_ENABLE || UNITY_EDITOR
|
#if TRACY_ENABLE
|
||||||
TracyInit();
|
TracyInit();
|
||||||
s_initialized = true;
|
s_initialized = true;
|
||||||
Debug.Log("[Tracy] 性能分析器已初始化");
|
Debug.Log("[Tracy] 性能分析器已初始化");
|
||||||
@@ -176,15 +178,14 @@ namespace TracyProfiler
|
|||||||
private bool isValid;
|
private bool isValid;
|
||||||
private string zoneName;
|
private string zoneName;
|
||||||
|
|
||||||
public ZoneScope(string name)
|
public ZoneScope(string name, string function = "", string file = "", int line = 0)
|
||||||
{
|
{
|
||||||
zoneName = name;
|
zoneName = name;
|
||||||
isValid = s_initialized && s_enabled;
|
isValid = s_initialized && s_enabled;
|
||||||
|
|
||||||
#if TRACY_ENABLE
|
#if TRACY_ENABLE
|
||||||
if (isValid)
|
if (isValid)
|
||||||
{
|
{
|
||||||
TracyZoneBegin(name);
|
TracyZoneScopedBegin(name, function, file, line);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -194,7 +195,7 @@ namespace TracyProfiler
|
|||||||
#if TRACY_ENABLE
|
#if TRACY_ENABLE
|
||||||
if (isValid && s_initialized && s_enabled)
|
if (isValid && s_initialized && s_enabled)
|
||||||
{
|
{
|
||||||
TracyZoneEnd();
|
TracyZoneScopedEnd(zoneName);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -210,31 +211,12 @@ namespace TracyProfiler
|
|||||||
/// // 要追踪的代码
|
/// // 要追踪的代码
|
||||||
/// }
|
/// }
|
||||||
/// </example>
|
/// </example>
|
||||||
public static ZoneScope Zone(string name)
|
public static ZoneScope Zone(string name,
|
||||||
|
[CallerMemberName] string function = "",
|
||||||
|
[CallerFilePath] string file = "",
|
||||||
|
[CallerLineNumber] int line = 0)
|
||||||
{
|
{
|
||||||
return new ZoneScope(name);
|
return new ZoneScope(name, function, file, line);
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 开始一个命名的 Zone
|
|
||||||
/// 注意:必须手动调用 EndZone() 结束,推荐使用 Zone() 方法配合 using 语句
|
|
||||||
/// </summary>
|
|
||||||
[System.Diagnostics.Conditional("TRACY_ENABLE")]
|
|
||||||
public static void BeginZone(string name)
|
|
||||||
{
|
|
||||||
if (!s_initialized || !s_enabled) return;
|
|
||||||
TracyZoneBegin(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 结束当前 Zone
|
|
||||||
/// 注意:必须与 BeginZone() 配对使用
|
|
||||||
/// </summary>
|
|
||||||
[System.Diagnostics.Conditional("TRACY_ENABLE")]
|
|
||||||
public static void EndZone()
|
|
||||||
{
|
|
||||||
if (!s_initialized || !s_enabled) return;
|
|
||||||
TracyZoneEnd();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user