Profiler.inl 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. // Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
  2. // SPDX-FileCopyrightText: 2021 Jorrit Rouwe
  3. // SPDX-License-Identifier: MIT
  4. JPH_NAMESPACE_BEGIN
  5. //////////////////////////////////////////////////////////////////////////////////////////
  6. // ProfileThread
  7. //////////////////////////////////////////////////////////////////////////////////////////
  8. ProfileThread::ProfileThread(const string_view &inThreadName) :
  9. mThreadName(inThreadName)
  10. {
  11. Profiler::sInstance->AddThread(this);
  12. }
  13. ProfileThread::~ProfileThread()
  14. {
  15. Profiler::sInstance->RemoveThread(this);
  16. }
  17. //////////////////////////////////////////////////////////////////////////////////////////
  18. // ProfileMeasurement
  19. //////////////////////////////////////////////////////////////////////////////////////////
  20. JPH_TSAN_NO_SANITIZE // TSAN reports a race on sOutOfSamplesReported, however the worst case is that we report the out of samples message multiple times
  21. ProfileMeasurement::ProfileMeasurement(const char *inName, uint32 inColor)
  22. {
  23. ProfileThread *current_thread = ProfileThread::sGetInstance();
  24. if (current_thread == nullptr)
  25. {
  26. // Thread not instrumented
  27. mSample = nullptr;
  28. }
  29. else if (current_thread->mCurrentSample < ProfileThread::cMaxSamples)
  30. {
  31. // Get pointer to write data to
  32. mSample = &current_thread->mSamples[current_thread->mCurrentSample++];
  33. // Start constructing sample (will end up on stack)
  34. mTemp.mName = inName;
  35. mTemp.mColor = inColor;
  36. // Collect start sample last
  37. mTemp.mStartCycle = GetProcessorTickCount();
  38. }
  39. else
  40. {
  41. // Out of samples
  42. if (!sOutOfSamplesReported)
  43. {
  44. sOutOfSamplesReported = true;
  45. Trace("ProfileMeasurement: Too many samples, some data will be lost!");
  46. }
  47. mSample = nullptr;
  48. }
  49. }
  50. ProfileMeasurement::~ProfileMeasurement()
  51. {
  52. if (mSample != nullptr)
  53. {
  54. // Finalize sample
  55. mTemp.mEndCycle = GetProcessorTickCount();
  56. // Write it to the memory buffer bypassing the cache
  57. static_assert(sizeof(ProfileSample) == 32, "Assume 32 bytes");
  58. static_assert(alignof(ProfileSample) == 16, "Assume 16 byte alignment");
  59. #if defined(JPH_USE_SSE)
  60. const __m128i *src = reinterpret_cast<const __m128i *>(&mTemp);
  61. __m128i *dst = reinterpret_cast<__m128i *>(mSample);
  62. __m128i val = _mm_loadu_si128(src);
  63. _mm_stream_si128(dst, val);
  64. val = _mm_loadu_si128(src + 1);
  65. _mm_stream_si128(dst + 1, val);
  66. #elif defined(JPH_USE_NEON)
  67. const int *src = reinterpret_cast<const int *>(&mTemp);
  68. int *dst = reinterpret_cast<int *>(mSample);
  69. int32x4_t val = vld1q_s32(src);
  70. vst1q_s32(dst, val);
  71. val = vld1q_s32(src + 4);
  72. vst1q_s32(dst + 4, val);
  73. #else
  74. memcpy(mSample, &mTemp, sizeof(ProfileSample));
  75. #endif
  76. mSample = nullptr;
  77. }
  78. }
  79. JPH_NAMESPACE_END