Skip to content

Commit eae3e20

Browse files
tf-marissawcopybara-github
authored andcommitted
Support Windows memory info
Memory info is a useful class for recording memory usage across a variety of devices. Add Windows support to it. PiperOrigin-RevId: 820360533
1 parent ac42fca commit eae3e20

File tree

3 files changed

+41
-3
lines changed

3 files changed

+41
-3
lines changed

tflite/profiling/memory_info.cc

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ limitations under the License.
2525
#elif defined(__APPLE__)
2626
#include <mach/mach.h>
2727
#include <malloc/malloc.h>
28+
#elif defined(_WIN32)
29+
#include <windows.h>
30+
// psapi must be included after windows.h.
31+
#include <psapi.h>
2832
#endif
2933

3034
namespace tflite {
@@ -34,7 +38,7 @@ namespace memory {
3438
const size_t MemoryUsage::kValueNotSet = 0;
3539

3640
bool MemoryUsage::IsSupported() {
37-
#if defined(__linux__) || defined(__APPLE__)
41+
#if defined(__linux__) || defined(__APPLE__) || defined(_WIN32)
3842
return true;
3943
#endif
4044
return false;
@@ -71,6 +75,30 @@ MemoryUsage GetMemoryUsage() {
7175
struct mstats stats = mstats();
7276
result.total_allocated_bytes = stats.bytes_total;
7377
result.in_use_allocated_bytes = stats.bytes_used;
78+
#elif defined(_WIN32)
79+
PROCESS_MEMORY_COUNTERS process_memory_counters;
80+
HANDLE process_handle = GetCurrentProcess();
81+
if (process_handle != nullptr &&
82+
GetProcessMemoryInfo(process_handle, &process_memory_counters,
83+
sizeof(process_memory_counters))) {
84+
result.mem_footprint_kb = process_memory_counters.WorkingSetSize / 1024;
85+
} else {
86+
result.mem_footprint_kb = -1;
87+
}
88+
CloseHandle(process_handle);
89+
HANDLE process_heap = GetProcessHeap();
90+
if (process_heap != nullptr && HeapLock(process_heap)) {
91+
HEAP_SUMMARY heap_summary;
92+
heap_summary.cb = sizeof(heap_summary);
93+
if (HeapSummary(process_heap, 0, &heap_summary)) {
94+
result.total_allocated_bytes = heap_summary.cbCommitted;
95+
result.in_use_allocated_bytes = heap_summary.cbAllocated;
96+
} else {
97+
result.total_allocated_bytes = -1;
98+
result.in_use_allocated_bytes = -1;
99+
}
100+
HeapUnlock(process_heap);
101+
}
74102
#endif // __linux__
75103
return result;
76104
}

tflite/profiling/memory_info.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,19 @@ struct MemoryUsage {
5555
// + purgeable_nonvolatile
5656
// + purgeable_nonvolatile_compressed
5757
// + page_table
58+
//
59+
// For Windows:
60+
// This is the current memory size (in kilobytes) occupied by the OS process
61+
// that is held in main memory (RAM). This is generally referred to as the
62+
// working set size. This is an alias to
63+
// PROCESS_MEMORY_COUNTERS::WorkingSetSize.
5864
int64_t mem_footprint_kb;
5965

6066
// Total non-mmapped heap space allocated from system in bytes.
6167
// For Linux, this is an alias to mallinfo::arena.
6268
// For Mac, this is an alias to mstats::bytes_total
69+
// For Windows, this is an alias to HEAP_SUMMARY::cbCommitted
70+
// for the default process heap.
6371
//
6472
// This does not count mmapped heap space, nor does it count non-heap
6573
// uses of memory such as other mmapped space, thread stacks, globals,
@@ -70,6 +78,8 @@ struct MemoryUsage {
7078
// (i.e. excluding those have been freed).
7179
// For Linux, this is an alias to mallinfo::uordblks.
7280
// For Mac, this is an alias to mstats::bytes_used
81+
// For Windows, this is an alias to HEAP_SUMMARY::cbAllocated
82+
// for the default process heap.
7383
//
7484
// This does not count non-heap uses of mmap, nor does it count other
7585
// non-heap uses of memory such as thread stacks, globals, code, etc.

tflite/profiling/memory_info_test.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ TEST(MemoryUsage, GetMemoryUsage) {
5252
EXPECT_EQ(MemoryUsage::kValueNotSet, result.total_allocated_bytes);
5353
EXPECT_EQ(MemoryUsage::kValueNotSet, result.in_use_allocated_bytes);
5454

55-
#if defined(__linux__) || defined(__APPLE__)
55+
#if defined(__linux__) || defined(__APPLE__) || defined(_WIN32)
5656
// Just allocate some space in heap so that we have some meaningful
5757
// memory usage to report.
5858
constexpr int size = 10 * 1024 * 1024;
@@ -89,7 +89,7 @@ TEST(MemoryUsage, OutputMemoryUsageToStream) {
8989
}
9090

9191
TEST(MemoryUsage, IsSupported) {
92-
#if defined(__linux__) || defined(__APPLE__)
92+
#if defined(__linux__) || defined(__APPLE__) || defined(_WIN32)
9393
EXPECT_TRUE(MemoryUsage::IsSupported());
9494
#else
9595
EXPECT_FALSE(MemoryUsage::IsSupported());

0 commit comments

Comments
 (0)