Resource Tracking for FlightGear: Difference between revisions

Jump to navigation Jump to search
→‎Proof of concept (patch): patch update for Nvidia GPU, and GPUInfo objects
mNo edit summary
(→‎Proof of concept (patch): patch update for Nvidia GPU, and GPUInfo objects)
Line 258: Line 258:
Here's a first stab at a simple subsystem to monitor FlightGear memory usage on Linux at 5 second intervals, consider it a "proof of concept" prototype now, as this would need to be cleaned up and implemented for Mac/Windows respectively - on Linux it simply works such that it merely fopen()s /proc/pid/smaps and copies two metrics to the property tree:
Here's a first stab at a simple subsystem to monitor FlightGear memory usage on Linux at 5 second intervals, consider it a "proof of concept" prototype now, as this would need to be cleaned up and implemented for Mac/Windows respectively - on Linux it simply works such that it merely fopen()s /proc/pid/smaps and copies two metrics to the property tree:
<syntaxhighlight lang="diff">
<syntaxhighlight lang="diff">
diff -urN a/src/Main/CMakeLists.txt b/src/Main/CMakeLists.txt
diff --git a/src/Main/CMakeLists.txt b/src/Main/CMakeLists.txt
--- a/src/Main/CMakeLists.txt 2015-08-20 23:03:15.070835000 +0300
index 4b6926e..31d3a8f 100644
+++ b/src/Main/CMakeLists.txt 2015-08-20 23:26:58.706798388 +0300
--- a/src/Main/CMakeLists.txt
@@ -17,12 +17,17 @@
+++ b/src/Main/CMakeLists.txt
main.cxx
@@ -17,12 +17,17 @@ set(SOURCES
options.cxx
main.cxx
util.cxx
options.cxx
+ ram_usage.cxx
util.cxx
positioninit.cxx
+ ram_usage.cxx
subsystemFactory.cxx
    positioninit.cxx
screensaver_control.cxx
    subsystemFactory.cxx
${RESOURCE_FILE}
    screensaver_control.cxx
)
${RESOURCE_FILE}
 
)
+IF(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
+IF(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
+ list(APPEND SOURCES ram_usage_linux.cxx)
+       list(APPEND SOURCES ram_usage_linux.cxx)
+ENDIF(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
+ENDIF(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
+
+
set(HEADERS
set(HEADERS
fg_commands.hxx
fg_commands.hxx
fg_init.hxx
fg_init.hxx
@@ -35,12 +40,19 @@
@@ -35,12 +40,19 @@ set(HEADERS
main.hxx
main.hxx
options.hxx
options.hxx
util.hxx
util.hxx
+ ram_usage.hxx
+ ram_usage.hxx
positioninit.hxx
    positioninit.hxx
subsystemFactory.hxx
    subsystemFactory.hxx
AircraftDirVisitorBase.hxx
    AircraftDirVisitorBase.hxx
screensaver_control.hxx
    screensaver_control.hxx
)
)
 
+IF(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
+IF(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
+ list(APPEND HEADERS ram_usage_linux.hxx)
+       list(APPEND HEADERS ram_usage_linux.hxx)
+ENDIF(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
+ENDIF(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
+
+
+
+
+
+
get_property(FG_SOURCES GLOBAL PROPERTY FG_SOURCES)
get_property(FG_SOURCES GLOBAL PROPERTY FG_SOURCES)
get_property(FG_HEADERS GLOBAL PROPERTY FG_HEADERS)
get_property(FG_HEADERS GLOBAL PROPERTY FG_HEADERS)
 
diff -urN a/src/Main/fg_init.cxx b/src/Main/fg_init.cxx
diff --git a/src/Main/fg_init.cxx b/src/Main/fg_init.cxx
--- a/src/Main/fg_init.cxx 2015-08-20 23:22:52.166804000 +0300
index 30ffa0e..5548f76 100644
+++ b/src/Main/fg_init.cxx 2015-08-20 23:29:15.074794813 +0300
--- a/src/Main/fg_init.cxx
+++ b/src/Main/fg_init.cxx
@@ -141,6 +141,7 @@
@@ -141,6 +141,7 @@
#include "globals.hxx"
#include "globals.hxx"
#include "logger.hxx"
#include "logger.hxx"
#include "main.hxx"
#include "main.hxx"
+#include "ram_usage.hxx"
+#include "ram_usage.hxx"
#include "positioninit.hxx"
#include "positioninit.hxx"
#include "util.hxx"
#include "util.hxx"
#include "AircraftDirVisitorBase.hxx"
#include "AircraftDirVisitorBase.hxx"
@@ -715,6 +716,10 @@
@@ -715,6 +716,10 @@ void fgCreateSubsystems(bool duringReset) {
////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////
globals->add_subsystem("properties", new FGProperties);
    globals->add_subsystem("properties", new FGProperties);
 
+ ////////////////////////////////////////////////////////////////////
+   ////////////////////////////////////////////////////////////////////
+ // Add the ram usage statistics system
+   // Add the ram usage statistics system
+ ////////////////////////////////////////////////////////////////////
+   ////////////////////////////////////////////////////////////////////
+ globals->add_subsystem("memory-stats", new MemoryUsageStats, SGSubsystemMgr::INIT, 5.00);
+   globals->add_subsystem("memory-stats", new MemoryUsageStats, SGSubsystemMgr::INIT, 5.00);
 
////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////
// Add the performance monitoring system.
    // Add the performance monitoring system.
diff -urN a/src/Main/ram_usage.cxx b/src/Main/ram_usage.cxx
diff --git a/src/Main/ram_usage.cxx b/src/Main/ram_usage.cxx
--- a/src/Main/ram_usage.cxx 1970-01-01 03:00:00.000000000 +0300
new file mode 100644
+++ b/src/Main/ram_usage.cxx 2015-08-20 23:29:53.950793794 +0300
index 0000000..a84ea7c
@@ -0,0 +1,22 @@
--- /dev/null
+++ b/src/Main/ram_usage.cxx
@@ -0,0 +1,25 @@
+#include "ram_usage_linux.hxx"
+#include "ram_usage_linux.hxx"
+
+
Line 337: Line 341:
+void
+void
+MemoryUsageStats::update(double dt) {
+MemoryUsageStats::update(double dt) {
+ _mem->update();
+   _mem->update();
+ double swap = _mem->getSwapSize();
+   int vram = _mem->getVRAMUsageInKB(); // vram stuff
+ double total = _mem->getTotalSize();
double swap = _mem->getSwapSize();
+ SG_LOG(SG_GENERAL, SG_DEBUG, "Updating Memory Stats:" << total << " kb");
+   double total = _mem->getTotalSize();
+ fgSetInt("/memory-usage/swap-usage-kb", swap );
+   SG_LOG(SG_GENERAL, SG_DEBUG, "Updating Memory Stats:" << total << " kb");
+ fgSetInt("/memory-usage/total-usage-kb", total );
+   fgSetInt("/memory-usage/swap-usage-kb", swap );
+   fgSetInt("/memory-usage/total-usage-kb", total );
+  fgSetInt("/memory-usage/vram-usage-kb", vram );
+}
+}
+
+
+
+
+
+
diff -urN a/src/Main/ram_usage.hxx b/src/Main/ram_usage.hxx
diff --git a/src/Main/ram_usage.hxx b/src/Main/ram_usage.hxx
--- a/src/Main/ram_usage.hxx 1970-01-01 03:00:00.000000000 +0300
new file mode 100644
+++ b/src/Main/ram_usage.hxx 2015-08-20 23:29:53.950793794 +0300
index 0000000..cef9cc2
@@ -0,0 +1,51 @@
--- /dev/null
+++ b/src/Main/ram_usage.hxx
@@ -0,0 +1,142 @@
+#ifndef __RAM_USAGE
+#ifndef __RAM_USAGE
+#define __RAM_USAGE
+#define __RAM_USAGE
+
+#include<stdio.h>
+#include<stdlib.h>
+#include<X11/X.h>
+#include<X11/Xlib.h>
+#include<GL/gl.h>
+#include<GL/glx.h>
+#include<GL/glu.h>
+
+
+
+#include <simgear/timing/timestamp.hxx>
+#include <simgear/timing/timestamp.hxx>
Line 364: Line 382:
+
+
+using std::map;
+using std::map;
+
+// http://www.geeks3d.com/20100531/programming-tips-how-to-know-the-graphics-memory-size-and-usage-in-opengl/
+#define GL_GPU_MEM_INFO_TOTAL_AVAILABLE_MEM_NVX 0x9048
+#define GL_GPU_MEM_INFO_CURRENT_AVAILABLE_MEM_NVX 0x9049
+
+    // this is the base class, with the only method being a virtual method
+    // which needs to be implemented by any child classes
+    // a pointer of this class will be added to the LinuxMemoryInterface class
+    class GPUInfo {
+    private:
+    protected:
+    public:
+    virtual ~GPUInfo() {};
+    virtual int getVRAMUsageInKB() = 0;
+    };
+
+    // Actually implement the GPUInfo class for all 3 GPU vendors:
+
+    class NVIDIA_GPU: public GPUInfo {
+    public:
+    virtual int getVRAMUsageInKB() {
+    GLint total_mem_kb = 0;
+    glGetIntegerv(GL_GPU_MEM_INFO_TOTAL_AVAILABLE_MEM_NVX,
+              &total_mem_kb);
+
+    GLint cur_avail_mem_kb = 0;
+    glGetIntegerv(GL_GPU_MEM_INFO_CURRENT_AVAILABLE_MEM_NVX,
+              &cur_avail_mem_kb);
+
+    SG_LOG(SG_GENERAL, SG_ALERT,"NVIDIA VRAM tracking function says:"<<total_mem_kb<<" (total) and used:"<<cur_avail_mem_kb);
+    return cur_avail_mem_kb;
+    }
+
+    };
+
+    class ATI_GPU: public GPUInfo {
+    public:
+    virtual int getVRAMUsageInKB() {
+    SG_LOG(SG_GENERAL, SG_ALERT,"ATI VRAM tracking function not yet implemented !");
+    return 200;
+    }
+
+    };
+
+    class INTEL_GPU : public GPUInfo {
+    public:
+    virtual int getVRAMUsageInKB() {
+    SG_LOG(SG_GENERAL, SG_ALERT,"Intel VRAM tracking function not yet implemented !");
+    return 500;
+    }
+
+    };
+
+
+// Linux: /proc/pid/smaps
+// Linux: /proc/pid/smaps
Line 370: Line 440:
+class MemoryInterface {
+class MemoryInterface {
+public:
+public:
+ MemoryInterface() {}
+ virtual ~MemoryInterface() {
+ delete _gpu;
+ };
+ MemoryInterface() {
+ // get the string
+    std::string fallback = "NVIDIA"; //default value
+
+    // get the actual GL vendor string from the property tree, using the fallback
+    std::string glvendor = fgGetString("/sim/rendering/gl-vendor",fallback.c_str() );
+
+    // make it upper case: http://stackoverflow.com/questions/735204/convert-a-string-in-c-to-upper-case
+    std::transform(glvendor.begin(), glvendor.end(), glvendor.begin(), ::toupper);
+
+    // look for the "NVIDIA" substring: http://www.cplusplus.com/reference/string/string/find/
+    std::size_t found = glvendor.find("NVIDIA");
+      if (found!=std::string::npos) {
+      SG_LOG(SG_GENERAL, SG_ALERT, "Supported GPU found: NVIDIA");
+      _gpu = new NVIDIA_GPU;
+    }
+
+ // else if ATI/AMD ...
+    // else if INTEL ...
+    else {
+    SG_LOG(SG_GENERAL, SG_ALERT, "Unsupported GPU vendor:" << glvendor);
+    }
+
+
+}
+ typedef map<const char*, double> RamMap;
+ typedef map<const char*, double> RamMap;
+//protected:
+//protected:
+ virtual void update() = 0;
+ virtual void update() = 0;
+
+ int getVRAMUsageInKB() const {return _gpu->getVRAMUsageInKB();}
+
+
+ double getTotalSize() const {return _total_size;}
+ double getTotalSize() const {return _total_size;}
+ //virtual void setTotalSize(double t) {_total_size=t;}
+ //virtual void   setTotalSize(double t) {_total_size=t;}
+
+  
+ double getSwapSize() const {return _swap_size;}
+ double getSwapSize() const {return _swap_size;}
+ //virtual void setSwapSize(double s) {_swap_size=s;}
+ //virtual void   setSwapSize(double s) {_swap_size=s;}
+protected:
+protected:
+ RamMap _size;
+ RamMap _size;  
+ std::string _path;
+ std::string _path;
+ std::stringstream _pid;
+ std::stringstream _pid;
+ GPUInfo* _gpu;
+
+
+ double _total_size;
+ double _total_size;
Line 392: Line 492:
+{
+{
+public:
+public:
+ MemoryUsageStats();
+ MemoryUsageStats();
+ ~MemoryUsageStats();
+ ~MemoryUsageStats();
+ virtual void update(double);
+ virtual void update(double);
+protected:
+protected:
+private:
+private:
+ MemoryInterface* _mem;
+ MemoryInterface* _mem;
+};
+};
+
+
+#endif
+#endif  
+
+
diff -urN a/src/Main/ram_usage_linux.cxx b/src/Main/ram_usage_linux.cxx
diff --git a/src/Main/ram_usage_linux.cxx b/src/Main/ram_usage_linux.cxx
--- a/src/Main/ram_usage_linux.cxx 1970-01-01 03:00:00.000000000 +0300
new file mode 100644
+++ b/src/Main/ram_usage_linux.cxx 2015-08-20 23:29:53.950793794 +0300
index 0000000..bb214a8
--- /dev/null
+++ b/src/Main/ram_usage_linux.cxx
@@ -0,0 +1,49 @@
@@ -0,0 +1,49 @@
+// https://gist.github.com/896026/c346c7c8e4a9ab18577b4e6abfca37e358de83c1
+// https://gist.github.com/896026/c346c7c8e4a9ab18577b4e6abfca37e358de83c1
Line 426: Line 528:
+ file = fopen(_path.c_str(),"r" );
+ file = fopen(_path.c_str(),"r" );
+ if (!file) {
+ if (!file) {
+ throw("MemoryTracker:Cannot open /proc/pid/smaps");
+       throw("MemoryTracker:Cannot open /proc/pid/smaps");
+ }
+   }
+ SG_LOG(SG_GENERAL, SG_DEBUG, "Opened:"<< _path.c_str() );
+ SG_LOG(SG_GENERAL, SG_DEBUG, "Opened:"<< _path.c_str() );
+}
+}
Line 439: Line 541:
+ if (!file) throw("MemoryTracker: ProcFile not open");
+ if (!file) throw("MemoryTracker: ProcFile not open");
+
+
+ _total_size = 0;
+ _total_size = 0;
+ _swap_size = 0;
+ _swap_size = 0;  
+
+
+ char line[1024];
+ char line[1024];
+ while (fgets(line, sizeof line, file))
+ while (fgets(line, sizeof line, file))
+ {
+   {
+ char substr[32];
+       char substr[32];
+ int n;
+       int n;
+ if (sscanf(line, "%31[^:]: %d", substr, &n) == 2) {
+       if (sscanf(line, "%31[^:]: %d", substr, &n) == 2) {
+ if (strcmp(substr, "Size") == 0) { _total_size += n; }
+         if (strcmp(substr, "Size") == 0)           { _total_size += n; }
+ else if (strcmp(substr, "Swap") == 0) { _swap_size += n; }
+               else   if (strcmp(substr, "Swap") == 0)           { _swap_size += n; }
+ }
+   }
+ }
+   }
+ fclose(file);
+ fclose(file);
+}
+}
+
+
diff -urN a/src/Main/ram_usage_linux.hxx b/src/Main/ram_usage_linux.hxx
diff --git a/src/Main/ram_usage_linux.hxx b/src/Main/ram_usage_linux.hxx
--- a/src/Main/ram_usage_linux.hxx 1970-01-01 03:00:00.000000000 +0300
new file mode 100644
+++ b/src/Main/ram_usage_linux.hxx 2015-08-20 23:29:53.950793794 +0300
index 0000000..59b7134
--- /dev/null
+++ b/src/Main/ram_usage_linux.hxx
@@ -0,0 +1,22 @@
@@ -0,0 +1,22 @@
+#ifndef __RAM_USAGE_LINUX
+#ifndef __RAM_USAGE_LINUX
Line 480: Line 584:
+
+
+
+
+#endif
+#endif</syntaxhighlight>
+
</syntaxhighlight>


[[Category:Core development projects]]
[[Category:Core development projects]]
272

edits

Navigation menu