perfaware/part2: Add bandwidth tracking
This commit is contained in:
		
							parent
							
								
									5817060a8b
								
							
						
					
					
						commit
						d01cf53ff8
					
				@ -3,94 +3,12 @@
 | 
				
			|||||||
#include <stdint.h>
 | 
					#include <stdint.h>
 | 
				
			||||||
#include <stdio.h>
 | 
					#include <stdio.h>
 | 
				
			||||||
#include <Windows.h>
 | 
					#include <Windows.h>
 | 
				
			||||||
#include "haversine_stdlib.h"
 | 
					 | 
				
			||||||
#include "haversine_stdlib.c"
 | 
					 | 
				
			||||||
#include <math.h>
 | 
					#include <math.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "haversine_stdlib.h"
 | 
				
			||||||
#include "listing_0065_haversine_formula.cpp"
 | 
					#include "listing_0065_haversine_formula.cpp"
 | 
				
			||||||
#include "listing_0074_platform_metrics.cpp"
 | 
					#include "listing_0074_platform_metrics.cpp"
 | 
				
			||||||
 | 
					#include "haversine_stdlib.c"
 | 
				
			||||||
typedef struct ProfilerAnchor {
 | 
					 | 
				
			||||||
    HAV_Str8 label;
 | 
					 | 
				
			||||||
    u64      elapsed_tsc_exclusive; // Does not include children
 | 
					 | 
				
			||||||
    u64      elapsed_tsc_inclusive; // Includes children
 | 
					 | 
				
			||||||
    u64      hits;
 | 
					 | 
				
			||||||
} ProfilerAnchor;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef struct Profiler {
 | 
					 | 
				
			||||||
    ProfilerAnchor anchors[4096];
 | 
					 | 
				
			||||||
    u64            begin_tsc;
 | 
					 | 
				
			||||||
    u64            end_tsc;
 | 
					 | 
				
			||||||
    u64            parent_index;
 | 
					 | 
				
			||||||
} Profiler;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static Profiler g_profiler;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void Profiler_Dump()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    u64 total_elapsed_tsc = g_profiler.end_tsc - g_profiler.begin_tsc;
 | 
					 | 
				
			||||||
    u64 cpu_frequency = EstimateCPUTimerFreq();
 | 
					 | 
				
			||||||
    if (cpu_frequency)
 | 
					 | 
				
			||||||
        printf("\nTotal time: %0.4fms (CPU freq %llu)\n", 1000.0 * (f64)total_elapsed_tsc / (f64)cpu_frequency, cpu_frequency);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    for (uint32_t index = 1; index < HAV_ARRAY_UCOUNT(g_profiler.anchors); index++) {
 | 
					 | 
				
			||||||
        ProfilerAnchor const *anchor = g_profiler.anchors + index;
 | 
					 | 
				
			||||||
        if (!anchor->elapsed_tsc_inclusive)
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        f64 percent = total_elapsed_tsc ? (f64)anchor->elapsed_tsc_exclusive / (f64)total_elapsed_tsc * 100.0 : 100.0;
 | 
					 | 
				
			||||||
        printf("   %.*s[%zu]: %llu (%.2f%%", HAV_STR8_FMT(anchor->label), anchor->hits, anchor->elapsed_tsc_exclusive, percent);
 | 
					 | 
				
			||||||
        if (anchor->elapsed_tsc_inclusive != anchor->elapsed_tsc_exclusive) {
 | 
					 | 
				
			||||||
            f64 percent_w_children = total_elapsed_tsc ? ((f64)anchor->elapsed_tsc_inclusive / (f64)total_elapsed_tsc * 100.0) : 100.0;
 | 
					 | 
				
			||||||
            printf(", %.2f%% w/children", percent_w_children);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        printf(")\n");
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef struct ProfilerZone {
 | 
					 | 
				
			||||||
    u64      parent_index;
 | 
					 | 
				
			||||||
    uint32_t index;
 | 
					 | 
				
			||||||
    HAV_Str8 label;
 | 
					 | 
				
			||||||
    u64      elapsed_tsc_inclusive;
 | 
					 | 
				
			||||||
    u64      tsc;
 | 
					 | 
				
			||||||
} ProfilerZone;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define Profiler_BeginZone(label) Profiler_BeginZone_(HAV_STR8(label), __COUNTER__ + 1)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static ProfilerZone Profiler_BeginZone_(HAV_Str8 label, uint32_t index)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    ProfilerZone result = {0};
 | 
					 | 
				
			||||||
    #if defined(HAV_PROFILER)
 | 
					 | 
				
			||||||
    result.index                 = index;
 | 
					 | 
				
			||||||
    result.label                 = label;
 | 
					 | 
				
			||||||
    result.tsc                   = ReadCPUTimer();
 | 
					 | 
				
			||||||
    result.elapsed_tsc_inclusive = g_profiler.anchors[index].elapsed_tsc_inclusive;
 | 
					 | 
				
			||||||
    result.parent_index          = g_profiler.parent_index;
 | 
					 | 
				
			||||||
    g_profiler.parent_index      = index;
 | 
					 | 
				
			||||||
    #else
 | 
					 | 
				
			||||||
    (void)label; (void)index;
 | 
					 | 
				
			||||||
    #endif
 | 
					 | 
				
			||||||
    return result;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void Profiler_EndZone(ProfilerZone zone)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    #if defined(HAV_PROFILER)
 | 
					 | 
				
			||||||
    u64 elapsed_tsc                = ReadCPUTimer() - zone.tsc;
 | 
					 | 
				
			||||||
    ProfilerAnchor* anchor         = g_profiler.anchors + zone.index;
 | 
					 | 
				
			||||||
    ProfilerAnchor* parent         = g_profiler.anchors + zone.parent_index;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    anchor->elapsed_tsc_exclusive += elapsed_tsc;
 | 
					 | 
				
			||||||
    anchor->elapsed_tsc_inclusive  = zone.elapsed_tsc_inclusive + elapsed_tsc;
 | 
					 | 
				
			||||||
    anchor->label                  = zone.label;
 | 
					 | 
				
			||||||
    anchor->hits++;
 | 
					 | 
				
			||||||
    parent->elapsed_tsc_exclusive -= elapsed_tsc;
 | 
					 | 
				
			||||||
    g_profiler.parent_index        = zone.parent_index;
 | 
					 | 
				
			||||||
    #else
 | 
					 | 
				
			||||||
    (void)zone;
 | 
					 | 
				
			||||||
    #endif
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct Str8FindResult {
 | 
					typedef struct Str8FindResult {
 | 
				
			||||||
    bool     found;
 | 
					    bool     found;
 | 
				
			||||||
@ -174,20 +92,17 @@ int main(int argc, char **argv)
 | 
				
			|||||||
    if (argc == 3)
 | 
					    if (argc == 3)
 | 
				
			||||||
        arg_answers = (HAV_Str8){.data = argv[2], .size = strlen(argv[2])};
 | 
					        arg_answers = (HAV_Str8){.data = argv[2], .size = strlen(argv[2])};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ProfilerZone prof_file_read_zone = Profiler_BeginZone("File Read");
 | 
					 | 
				
			||||||
    HAV_Buffer json_buffer = HAV_FileRead(arg_json.data);
 | 
					    HAV_Buffer json_buffer = HAV_FileRead(arg_json.data);
 | 
				
			||||||
    Profiler_EndZone(prof_file_read_zone);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (!HAV_BufferIsValid(json_buffer))
 | 
					    if (!HAV_BufferIsValid(json_buffer))
 | 
				
			||||||
        return 0;
 | 
					        return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ProfilerZone prof_parse_and_sum_zone = Profiler_BeginZone("Parse&Hav Sum");
 | 
					    HAV_ProfilerZone prof_parse_and_sum_zone = HAV_Profiler_BeginZone("Parse&Hav Sum");
 | 
				
			||||||
    f64 haversine_sum = 0;
 | 
					    f64 haversine_sum = 0;
 | 
				
			||||||
    size_t pair_count = 0;
 | 
					    size_t pair_count = 0;
 | 
				
			||||||
    HAV_Str8 json_it  = (HAV_Str8){.data = json_buffer.data, .size = json_buffer.size};
 | 
					    HAV_Str8 json_it  = (HAV_Str8){.data = json_buffer.data, .size = json_buffer.size};
 | 
				
			||||||
    for (;; pair_count++) {
 | 
					    for (;; pair_count++) {
 | 
				
			||||||
        ProfilerZone prof_json_parse_zone = Profiler_BeginZone("Parse");
 | 
					 | 
				
			||||||
        f64 x0 = 0.f, y0 = 0.f, x1 = 0.f, y1 = 0.f;
 | 
					        f64 x0 = 0.f, y0 = 0.f, x1 = 0.f, y1 = 0.f;
 | 
				
			||||||
 | 
					        HAV_ProfilerZone prof_json_parse_zone = HAV_Profiler_BeginZoneBandwidth("Parse", json_it.size);
 | 
				
			||||||
        HAV_Str8BinarySplitResult x0_key = HAV_Str8_BinarySplit(json_it, HAV_STR8("x0"));
 | 
					        HAV_Str8BinarySplitResult x0_key = HAV_Str8_BinarySplit(json_it, HAV_STR8("x0"));
 | 
				
			||||||
        if (x0_key.rhs.size) {
 | 
					        if (x0_key.rhs.size) {
 | 
				
			||||||
            Str8FindResult            x0_find_value = FindFirstCharThatLooksLikeANumber(x0_key.rhs);
 | 
					            Str8FindResult            x0_find_value = FindFirstCharThatLooksLikeANumber(x0_key.rhs);
 | 
				
			||||||
@ -220,16 +135,16 @@ int main(int argc, char **argv)
 | 
				
			|||||||
                       HAV_STR8_FMT(y1_value.lhs), y1);
 | 
					                       HAV_STR8_FMT(y1_value.lhs), y1);
 | 
				
			||||||
        #endif
 | 
					        #endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Profiler_EndZone(prof_json_parse_zone);
 | 
					        HAV_Profiler_EndZone(prof_json_parse_zone);
 | 
				
			||||||
        if (!x0_key.rhs.size)
 | 
					        if (!x0_key.rhs.size)
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        ProfilerZone prof_haversine_sum_zone = Profiler_BeginZone("Hav Sum");
 | 
					        HAV_ProfilerZone prof_haversine_sum_zone = HAV_Profiler_BeginZoneBandwidth("Hav Sum", sizeof(x0) + sizeof(y0) + sizeof(x1) + sizeof(y1));
 | 
				
			||||||
        f64 haversine_dist = ReferenceHaversine(x0, y0, x1, y1, /*EarthRadius*/ 6372.8);
 | 
					        f64 haversine_dist = ReferenceHaversine(x0, y0, x1, y1, /*EarthRadius*/ 6372.8);
 | 
				
			||||||
        haversine_sum     += haversine_dist;
 | 
					        haversine_sum     += haversine_dist;
 | 
				
			||||||
        Profiler_EndZone(prof_haversine_sum_zone);
 | 
					        HAV_Profiler_EndZone(prof_haversine_sum_zone);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    Profiler_EndZone(prof_parse_and_sum_zone);
 | 
					    HAV_Profiler_EndZone(prof_parse_and_sum_zone);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    haversine_sum /= pair_count;
 | 
					    haversine_sum /= pair_count;
 | 
				
			||||||
    size_t input_size = json_buffer.size;
 | 
					    size_t input_size = json_buffer.size;
 | 
				
			||||||
@ -253,6 +168,6 @@ int main(int argc, char **argv)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    g_profiler.end_tsc = ReadCPUTimer();
 | 
					    g_profiler.end_tsc = ReadCPUTimer();
 | 
				
			||||||
    Profiler_Dump();
 | 
					    HAV_Profiler_Dump();
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -3,10 +3,12 @@
 | 
				
			|||||||
#include <stdint.h>
 | 
					#include <stdint.h>
 | 
				
			||||||
#include <stdio.h>
 | 
					#include <stdio.h>
 | 
				
			||||||
#include <Windows.h>
 | 
					#include <Windows.h>
 | 
				
			||||||
#include "haversine_stdlib.h"
 | 
					 | 
				
			||||||
#include "haversine_stdlib.c"
 | 
					 | 
				
			||||||
#include <math.h>
 | 
					#include <math.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "haversine_stdlib.h"
 | 
				
			||||||
 | 
					#include "listing_0074_platform_metrics.cpp"
 | 
				
			||||||
#include "listing_0065_haversine_formula.cpp"
 | 
					#include "listing_0065_haversine_formula.cpp"
 | 
				
			||||||
 | 
					#include "haversine_stdlib.c"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define PRINT_USAGE HAV_PrintLnFmt("Usage: %s [uniform/cluster] [random seed] [number of coordinate pairs to generate]", argv[0])
 | 
					#define PRINT_USAGE HAV_PrintLnFmt("Usage: %s [uniform/cluster] [random seed] [number of coordinate pairs to generate]", argv[0])
 | 
				
			||||||
int main(int argc, char **argv)
 | 
					int main(int argc, char **argv)
 | 
				
			||||||
 | 
				
			|||||||
@ -55,6 +55,73 @@ bool HAV_CharIsDigit(char ch)
 | 
				
			|||||||
    return result;
 | 
					    return result;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void HAV_Profiler_Dump()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    u64 total_elapsed_tsc = g_profiler.end_tsc - g_profiler.begin_tsc;
 | 
				
			||||||
 | 
					    u64 cpu_frequency = EstimateCPUTimerFreq();
 | 
				
			||||||
 | 
					    if (cpu_frequency)
 | 
				
			||||||
 | 
					        printf("\nTotal time: %0.4fms (CPU freq %llu)\n", 1000.0 * (f64)total_elapsed_tsc / (f64)cpu_frequency, cpu_frequency);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (uint32_t index = 1; index < HAV_ARRAY_UCOUNT(g_profiler.anchors); index++) {
 | 
				
			||||||
 | 
					        HAV_ProfilerAnchor const *anchor = g_profiler.anchors + index;
 | 
				
			||||||
 | 
					        if (!anchor->elapsed_tsc_inclusive)
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        f64 percent = total_elapsed_tsc ? (f64)anchor->elapsed_tsc_exclusive / (f64)total_elapsed_tsc * 100.0 : 100.0;
 | 
				
			||||||
 | 
					        printf("   %.*s[%zu]: %llu (%.2f%%", HAV_STR8_FMT(anchor->label), anchor->hits, anchor->elapsed_tsc_exclusive, percent);
 | 
				
			||||||
 | 
					        if (anchor->elapsed_tsc_inclusive != anchor->elapsed_tsc_exclusive) {
 | 
				
			||||||
 | 
					            f64 percent_w_children = total_elapsed_tsc ? ((f64)anchor->elapsed_tsc_inclusive / (f64)total_elapsed_tsc * 100.0) : 100.0;
 | 
				
			||||||
 | 
					            printf(", %.2f%% w/children", percent_w_children);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        printf(")");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (anchor->byte_count) {
 | 
				
			||||||
 | 
					            f64 megabytes_processed = anchor->byte_count / (1024.f * 1024.f);
 | 
				
			||||||
 | 
					            f64 elapsed_s           = anchor->elapsed_tsc_inclusive / HAV_CAST(f64)cpu_frequency;
 | 
				
			||||||
 | 
					            f64 bytes_per_s         = anchor->byte_count / elapsed_s;
 | 
				
			||||||
 | 
					            f64 gigabytes_bandwidth = bytes_per_s / (1024.f * 1024.f * 1024.f);
 | 
				
			||||||
 | 
					            printf("  %.3fmb at %.2fgb/s", megabytes_processed, gigabytes_bandwidth);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        printf("\n");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					HAV_ProfilerZone HAV_Profiler_BeginZone_(HAV_Str8 label, uint32_t index, u64 byte_count)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    HAV_ProfilerZone result      = {0};
 | 
				
			||||||
 | 
					    #if defined(HAV_PROFILER)
 | 
				
			||||||
 | 
					    result.index                 = index;
 | 
				
			||||||
 | 
					    result.label                 = label;
 | 
				
			||||||
 | 
					    result.tsc                   = ReadCPUTimer();
 | 
				
			||||||
 | 
					    result.elapsed_tsc_inclusive = g_profiler.anchors[index].elapsed_tsc_inclusive;
 | 
				
			||||||
 | 
					    result.byte_count            = byte_count;
 | 
				
			||||||
 | 
					    result.parent_index          = g_profiler.parent_index;
 | 
				
			||||||
 | 
					    g_profiler.parent_index      = index;
 | 
				
			||||||
 | 
					    #else
 | 
				
			||||||
 | 
					    (void)label; (void)index; (void)byte_count;
 | 
				
			||||||
 | 
					    #endif
 | 
				
			||||||
 | 
					    return result;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void HAV_Profiler_EndZone(HAV_ProfilerZone zone)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    #if defined(HAV_PROFILER)
 | 
				
			||||||
 | 
					    u64 elapsed_tsc             = ReadCPUTimer() - zone.tsc;
 | 
				
			||||||
 | 
					    HAV_ProfilerAnchor* anchor  = g_profiler.anchors + zone.index;
 | 
				
			||||||
 | 
					    HAV_ProfilerAnchor* parent  = g_profiler.anchors + zone.parent_index;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    anchor->elapsed_tsc_exclusive += elapsed_tsc;
 | 
				
			||||||
 | 
					    anchor->elapsed_tsc_inclusive  = zone.elapsed_tsc_inclusive + elapsed_tsc;
 | 
				
			||||||
 | 
					    anchor->label                  = zone.label;
 | 
				
			||||||
 | 
					    anchor->byte_count            += zone.byte_count;
 | 
				
			||||||
 | 
					    anchor->hits++;
 | 
				
			||||||
 | 
					    parent->elapsed_tsc_exclusive -= elapsed_tsc;
 | 
				
			||||||
 | 
					    g_profiler.parent_index        = zone.parent_index;
 | 
				
			||||||
 | 
					    #else
 | 
				
			||||||
 | 
					    (void)zone;
 | 
				
			||||||
 | 
					    #endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#pragma warning(push)
 | 
					#pragma warning(push)
 | 
				
			||||||
#pragma warning(disable: 4146) // warning C4146: unary minus operator applied to unsigned type, result still unsigned
 | 
					#pragma warning(disable: 4146) // warning C4146: unary minus operator applied to unsigned type, result still unsigned
 | 
				
			||||||
uint32_t HAV_PCG32_Pie (uint64_t *state)
 | 
					uint32_t HAV_PCG32_Pie (uint64_t *state)
 | 
				
			||||||
@ -152,6 +219,7 @@ HAV_Buffer HAV_FileRead(char const *file_path)
 | 
				
			|||||||
    // NOTE: Read file to buffer
 | 
					    // NOTE: Read file to buffer
 | 
				
			||||||
    // =========================================================================
 | 
					    // =========================================================================
 | 
				
			||||||
    DWORD bytes_read = 0;
 | 
					    DWORD bytes_read = 0;
 | 
				
			||||||
 | 
					    HAV_ProfilerZone prof_file_read_zone = HAV_Profiler_BeginZoneBandwidth("File Read", file_size);
 | 
				
			||||||
    BOOL read_file_result = ReadFile(
 | 
					    BOOL read_file_result = ReadFile(
 | 
				
			||||||
      /*HANDLE       hFile*/ file_handle,
 | 
					      /*HANDLE       hFile*/ file_handle,
 | 
				
			||||||
      /*LPVOID       lpBuffer*/ buffer,
 | 
					      /*LPVOID       lpBuffer*/ buffer,
 | 
				
			||||||
@ -159,6 +227,7 @@ HAV_Buffer HAV_FileRead(char const *file_path)
 | 
				
			|||||||
      /*LPDWORD      lpNumberOfBytesRead*/ &bytes_read,
 | 
					      /*LPDWORD      lpNumberOfBytesRead*/ &bytes_read,
 | 
				
			||||||
      /*LPOVERLAPPED lpOverlapped*/ NULL
 | 
					      /*LPOVERLAPPED lpOverlapped*/ NULL
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
 | 
					    HAV_Profiler_EndZone(prof_file_read_zone);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // NOTE: Handle read result
 | 
					    // NOTE: Handle read result
 | 
				
			||||||
    // =========================================================================
 | 
					    // =========================================================================
 | 
				
			||||||
 | 
				
			|||||||
@ -60,6 +60,41 @@ HAV_Str8BinarySplitResult HAV_Str8_BinarySplit(HAV_Str8 buffer, HAV_Str8 find);
 | 
				
			|||||||
bool                      HAV_CharIsWhiteSpace(char ch);
 | 
					bool                      HAV_CharIsWhiteSpace(char ch);
 | 
				
			||||||
bool                      HAV_CharIsDigit(char ch);
 | 
					bool                      HAV_CharIsDigit(char ch);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// NOTE: Profiler
 | 
				
			||||||
 | 
					// ============================================================================
 | 
				
			||||||
 | 
					typedef struct HAV_ProfilerAnchor {
 | 
				
			||||||
 | 
					    HAV_Str8 label;
 | 
				
			||||||
 | 
					    u64      elapsed_tsc_exclusive; // Does not include children
 | 
				
			||||||
 | 
					    u64      elapsed_tsc_inclusive; // Includes children
 | 
				
			||||||
 | 
					    u64      byte_count;
 | 
				
			||||||
 | 
					    u64      hits;
 | 
				
			||||||
 | 
					} HAV_ProfilerAnchor;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct HAV_Profiler {
 | 
				
			||||||
 | 
					    HAV_ProfilerAnchor anchors[4096];
 | 
				
			||||||
 | 
					    u64                begin_tsc;
 | 
				
			||||||
 | 
					    u64                end_tsc;
 | 
				
			||||||
 | 
					    u64                parent_index;
 | 
				
			||||||
 | 
					} HAV_Profiler;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct HAV_ProfilerZone {
 | 
				
			||||||
 | 
					    u64      parent_index;
 | 
				
			||||||
 | 
					    uint32_t index;
 | 
				
			||||||
 | 
					    HAV_Str8 label;
 | 
				
			||||||
 | 
					    u64      elapsed_tsc_inclusive;
 | 
				
			||||||
 | 
					    u64      tsc;
 | 
				
			||||||
 | 
					    u64      byte_count;
 | 
				
			||||||
 | 
					} HAV_ProfilerZone;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static HAV_Profiler g_profiler;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define HAV_Profiler_BeginZone(label) HAV_Profiler_BeginZone_(HAV_STR8(label), __COUNTER__ + 1, 0)
 | 
				
			||||||
 | 
					#define HAV_Profiler_BeginZoneBandwidth(label, byte_count) HAV_Profiler_BeginZone_(HAV_STR8(label), __COUNTER__ + 1, byte_count)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void HAV_Profiler_Dump();
 | 
				
			||||||
 | 
					static HAV_ProfilerZone HAV_Profiler_BeginZone_(HAV_Str8 label, uint32_t index, u64 byte_count);
 | 
				
			||||||
 | 
					static void HAV_Profiler_EndZone(HAV_ProfilerZone zone);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// NOTE: PCG32
 | 
					// NOTE: PCG32
 | 
				
			||||||
// ============================================================================
 | 
					// ============================================================================
 | 
				
			||||||
// NOTE: PCG RNG from Demetri Spanos: https://github.com/demetri/scribbles
 | 
					// NOTE: PCG RNG from Demetri Spanos: https://github.com/demetri/scribbles
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user