Exemplo n.º 1
0
        private ProfileData GetData(ProfilerFrameDataIterator frameData, int firstFrameIndex, int lastFrameIndex)
        {
            var data = new ProfileData();

            data.SetFrameIndexOffset(firstFrameIndex);

            Dictionary <string, int> threadNameCount = new Dictionary <string, int>();

            for (int frameIndex = firstFrameIndex; frameIndex <= lastFrameIndex; ++frameIndex)
            {
                m_progressBar.AdvanceProgressBar();

                int threadCount = frameData.GetThreadCount(frameIndex);
                frameData.SetRoot(frameIndex, 0);

                var msFrame = frameData.frameTimeMS;

                /*
                 * if (frameIndex == lastFrameIndex)
                 * {
                 *  // Check if last frame appears to be invalid data
                 *  float median;
                 *  float mean;
                 *  float standardDeviation;
                 *  CalculateFrameTimeStats(data, out median, out mean, out standardDeviation);
                 *  float execessiveDeviation = (3f * standardDeviation);
                 *  if (msFrame > (median + execessiveDeviation))
                 *  {
                 *      Debug.LogFormat("Dropping last frame as it is significantly larger than the median of the rest of the data set {0} > {1} (median {2} + 3 * standard deviation {3})", msFrame, median + execessiveDeviation, median, standardDeviation);
                 *      break;
                 *  }
                 *  if (msFrame < (median - execessiveDeviation))
                 *  {
                 *      Debug.LogFormat("Dropping last frame as it is significantly smaller than the median of the rest of the data set {0} < {1} (median {2} - 3 * standard deviation {3})", msFrame, median - execessiveDeviation, median, standardDeviation);
                 *      break;
                 *  }
                 * }
                 */

                ProfileFrame frame = new ProfileFrame();
                frame.msStartTime = 1000.0 * frameData.GetFrameStartS(frameIndex);
                frame.msFrame     = msFrame;
                data.Add(frame);

                threadNameCount.Clear();
                for (int threadIndex = 0; threadIndex < threadCount; ++threadIndex)
                {
                    frameData.SetRoot(frameIndex, threadIndex);

                    var threadName = frameData.GetThreadName();
                    if (threadName.Trim() == "")
                    {
                        Debug.Log(string.Format("Warning: Unnamed thread found on frame {0}. Corrupted data suspected, ignoring frame", frameIndex));
                        continue;
                    }

                    var groupName = frameData.GetGroupName();
                    threadName = ProfileData.GetThreadNameWithGroup(threadName, groupName);

                    ProfileThread thread = new ProfileThread();
                    frame.Add(thread);

                    int nameCount = 0;
                    threadNameCount.TryGetValue(threadName, out nameCount);
                    threadNameCount[threadName] = nameCount + 1;

                    data.AddThreadName(ProfileData.ThreadNameWithIndex(threadNameCount[threadName], threadName), thread);

                    const bool enterChildren = true;
                    // The markers are in depth first order and the depth is known
                    // So we can infer a parent child relationship
                    while (frameData.Next(enterChildren))
                    {
                        var markerData = ProfileMarker.Create(frameData);

                        data.AddMarkerName(frameData.name, markerData);
                        thread.Add(markerData);
                    }
                }
            }

            data.Finalise();

            return(data);
        }
Exemplo n.º 2
0
        public ProfileAnalysis Analyze(ProfileData profileData, List <int> selectionIndices, List <string> threadFilters, int depthFilter, bool selfTimes = false, string parentMarker = null, float timeScaleMax = 0)
        {
            m_Progress = 0;
            if (profileData == null)
            {
                return(null);
            }
            if (profileData.GetFrameCount() <= 0)
            {
                return(null);
            }

            int frameCount = selectionIndices.Count;

            if (frameCount <= 0)
            {
                return(null);
            }

            bool processMarkers = (threadFilters != null);

            ProfileAnalysis analysis = new ProfileAnalysis();

            analysis.SetRange(selectionIndices[0], selectionIndices[selectionIndices.Count - 1]);

            m_threadNames.Clear();

            int maxMarkerDepthFound = 0;
            var threads             = new Dictionary <string, ThreadData>();
            var markers             = new Dictionary <string, MarkerData>();
            var allMarkers          = new Dictionary <string, int>();


            bool filteringByParentMarker = false;
            int  parentMarkerIndex       = -1;

            if (!IsNullOrWhiteSpace(parentMarker))
            {
                // Returns -1 if this marker doesn't exist in the data set
                parentMarkerIndex       = profileData.GetMarkerIndex(parentMarker);
                filteringByParentMarker = true;
            }

            int at = 0;

            foreach (int frameIndex in selectionIndices)
            {
                int frameOffset = profileData.DisplayFrameToOffset(frameIndex);
                var frameData   = profileData.GetFrame(frameOffset);
                if (frameData == null)
                {
                    continue;
                }
                var msFrame = frameData.msFrame;

                analysis.UpdateSummary(frameIndex, msFrame);

                if (processMarkers)
                {
                    for (int threadIndex = 0; threadIndex < frameData.threads.Count; threadIndex++)
                    {
                        float msTimeOfMinDepthMarkers     = 0.0f;
                        float msIdleTimeOfMinDepthMarkers = 0.0f;

                        var threadData          = frameData.threads[threadIndex];
                        var threadNameWithIndex = profileData.GetThreadName(threadData);

                        ThreadData thread;
                        if (!threads.ContainsKey(threadNameWithIndex))
                        {
                            m_threadNames.Add(threadNameWithIndex);

                            thread = new ThreadData(threadNameWithIndex);

                            analysis.AddThread(thread);
                            threads[threadNameWithIndex] = thread;

                            // Update threadsInGroup for all thread records of the same group name
                            foreach (var threadAt in threads.Values)
                            {
                                if (threadAt == thread)
                                {
                                    continue;
                                }

                                if (thread.threadGroupName == threadAt.threadGroupName)
                                {
                                    threadAt.threadsInGroup += 1;
                                    thread.threadsInGroup   += 1;
                                }
                            }
                        }
                        else
                        {
                            thread = threads[threadNameWithIndex];
                        }

                        bool include = MatchThreadFilter(threadNameWithIndex, threadFilters);

                        int parentMarkerDepth = -1;
                        foreach (ProfileMarker markerData in threadData.markers)
                        {
                            string markerName = profileData.GetMarkerName(markerData);
                            if (!allMarkers.ContainsKey(markerName))
                            {
                                allMarkers.Add(markerName, 1);
                            }
                            // No longer counting how many times we see the marker (this saves 1/3 of the analysis time).

                            float ms          = markerData.msMarkerTotal - (selfTimes ? markerData.msChildren : 0);
                            var   markerDepth = markerData.depth;
                            if (markerDepth > maxMarkerDepthFound)
                            {
                                maxMarkerDepthFound = markerDepth;
                            }

                            if (markerDepth == 1)
                            {
                                if (markerName == "Idle")
                                {
                                    msIdleTimeOfMinDepthMarkers += ms;
                                }
                                else
                                {
                                    msTimeOfMinDepthMarkers += ms;
                                }
                            }

                            if (!include)
                            {
                                continue;
                            }

                            if (depthFilter >= 0 && markerDepth != depthFilter)
                            {
                                continue;
                            }

                            // If only looking for markers below the parent
                            if (filteringByParentMarker)
                            {
                                // If found the parent marker
                                if (markerData.nameIndex == parentMarkerIndex)
                                {
                                    // And we are not already below the parent higher in the depth tree
                                    if (parentMarkerDepth < 0)
                                    {
                                        // record the parent marker depth
                                        parentMarkerDepth = markerData.depth;
                                    }
                                }
                                else
                                {
                                    // If we are now above or beside the parent marker then we are done for this level
                                    if (markerData.depth <= parentMarkerDepth)
                                    {
                                        parentMarkerDepth = -1;
                                    }
                                }

                                if (parentMarkerDepth < 0)
                                {
                                    continue;
                                }
                            }

                            MarkerData marker;
                            if (markers.ContainsKey(markerName))
                            {
                                marker = markers[markerName];
                            }
                            else
                            {
                                marker = new MarkerData(markerName);
                                marker.firstFrameIndex = frameIndex;
                                marker.minDepth        = markerDepth;
                                marker.maxDepth        = markerDepth;
                                analysis.AddMarker(marker);
                                markers.Add(markerName, marker);
                            }

                            marker.count   += 1;
                            marker.msTotal += ms;

                            // Individual marker time (not total over frame)
                            if (ms < marker.msMinIndividual)
                            {
                                marker.msMinIndividual         = ms;
                                marker.minIndividualFrameIndex = frameIndex;
                            }
                            if (ms > marker.msMaxIndividual)
                            {
                                marker.msMaxIndividual         = ms;
                                marker.maxIndividualFrameIndex = frameIndex;
                            }

                            // Record highest depth foun
                            if (markerDepth < marker.minDepth)
                            {
                                marker.minDepth = markerDepth;
                            }
                            if (markerDepth > marker.maxDepth)
                            {
                                marker.maxDepth = markerDepth;
                            }

                            FrameTime frameTime;
                            if (frameIndex != marker.lastFrame)
                            {
                                marker.presentOnFrameCount += 1;
                                frameTime = new FrameTime(frameIndex, ms, 1);
                                marker.frames.Add(frameTime);
                                marker.lastFrame = frameIndex;
                            }
                            else
                            {
                                frameTime = marker.frames[marker.frames.Count - 1];
                                frameTime = new FrameTime(frameTime.frameIndex, frameTime.ms + ms, frameTime.count + 1);
                                marker.frames[marker.frames.Count - 1] = frameTime;
                            }
                        }

                        if (include)
                        {
                            thread.frames.Add(new ThreadFrameTime(frameIndex, msTimeOfMinDepthMarkers, msIdleTimeOfMinDepthMarkers));
                        }
                    }
                }

                at++;
                m_Progress = (100 * at) / frameCount;
            }

            analysis.GetFrameSummary().totalMarkers = allMarkers.Count;
            analysis.Finalise(timeScaleMax, maxMarkerDepthFound);

            /*
             * foreach (int frameIndex in selectionIndices)
             * {
             *  int frameOffset = profileData.DisplayFrameToOffset(frameIndex);
             *
             *  var frameData = profileData.GetFrame(frameOffset);
             *  foreach (var threadData in frameData.threads)
             *  {
             *      var threadNameWithIndex = profileData.GetThreadName(threadData);
             *
             *      if (filterThreads && threadFilter != threadNameWithIndex)
             *          continue;
             *
             *      const bool enterChildren = true;
             *      foreach (var markerData in threadData.markers)
             *      {
             *          var markerName = markerData.name;
             *          var ms = markerData.msFrame;
             *          var markerDepth = markerData.depth;
             *          if (depthFilter>=0 && markerDepth != depthFilter)
             *              continue;
             *
             *          MarkerData marker = markers[markerName];
             *          bucketIndex = (range > 0) ? (int)(((marker.buckets.Length-1) * (ms - first)) / range) : 0;
             *          if (bucketIndex<0 || bucketIndex > (marker.buckets.Length - 1))
             *          {
             *              // This can happen if a single marker range is longer than the frame start end (which could occur if running on a separate thread)
             *              // Debug.Log(string.Format("Marker {0} : {1}ms exceeds range {2}-{3} on frame {4}", marker.name, ms, first, last, frameIndex));
             *              if (bucketIndex > (marker.buckets.Length - 1))
             *                  bucketIndex = (marker.buckets.Length - 1);
             *              else
             *                  bucketIndex = 0;
             *          }
             *          marker.individualBuckets[bucketIndex] += 1;
             *      }
             *  }
             * }
             */
            m_Progress = 100;
            return(analysis);
        }
Exemplo n.º 3
0
        private bool GetMarkerInfo(string markerName, int frameIndex, List <string> threadFilters, out int outThreadIndex, out float time, out float duration, out int instanceId)
        {
            ProfilerFrameDataIterator frameData = new ProfilerFrameDataIterator();

            outThreadIndex = 0;
            time           = 0.0f;
            duration       = 0.0f;
            instanceId     = 0;
            bool found = false;

            int threadCount = frameData.GetThreadCount(frameIndex);
            Dictionary <string, int> threadNameCount = new Dictionary <string, int>();

            for (int threadIndex = 0; threadIndex < threadCount; ++threadIndex)
            {
                frameData.SetRoot(frameIndex, threadIndex);

                var threadName = frameData.GetThreadName();
                // Name here could be "Worker Thread 1"

                var groupName = frameData.GetGroupName();
                threadName = ProfileData.GetThreadNameWithGroup(threadName, groupName);

                int nameCount = 0;
                threadNameCount.TryGetValue(threadName, out nameCount);
                threadNameCount[threadName] = nameCount + 1;

                var threadNameWithIndex = ProfileData.ThreadNameWithIndex(threadNameCount[threadName], threadName);

                // To compare on the filter we need to remove the postfix on the thread name
                // "3:Worker Thread 0" -> "1:Worker Thread"
                // The index of the thread (0) is used +1 as a prefix
                // The preceding number (3) is the count of number of threads with this name
                // Unfortunately multiple threads can have the same name
                threadNameWithIndex = ProfileData.CorrectThreadName(threadNameWithIndex);

                if (threadFilters.Contains(threadNameWithIndex))
                {
                    const bool enterChildren = true;
                    while (frameData.Next(enterChildren))
                    {
                        if (frameData.name == markerName)
                        {
                            time           = frameData.startTimeMS;
                            duration       = frameData.durationMS;
                            instanceId     = frameData.instanceId;
                            outThreadIndex = threadIndex;
                            found          = true;
                            break;
                        }
                    }
                }

                if (found)
                {
                    break;
                }
            }

            frameData.Dispose();
            return(found);
        }