1

I have a C++ application and I want to profile the CPU, GPU and RAM usage.

All this info can be found in the Monitor Control app for macOS

Screenshot of Activity Monitor

Right now I'm getting this information through a shell command

const std::string getCPUCommand =
    "ps -p " + std::to_string(pid) + " -o %cpu | awk 'FNR == 2 {print $1}'";

But this only gets CPU usage, not GPU, and is also a not very performant command.

Is there any better alternative to get all this information?

Jorengarenar
  • 2,705
  • 5
  • 23
  • 60
ellipticaldoor
  • 1,122
  • 11
  • 24

1 Answers1

2

Regarding CPU and RAM usage it has been answered in this post

Briefly-

Swap/Virtual Memory

#include <sys/param.h>
#include <sys/mount.h>

struct statfs stats;
if(statfs("/",&stats)==0)
    FreeSwap=(unisgned long long)stats.f_bsize * stats.f_bfree;

the xsw_usage struct is used to find total swap memory used

xsw_usage used_swap={0};

unsigned int size=sizeof(used_swap);

RAM

Ram currently used-

#include <mach/vm_statistics.h>
#include <mach/mach_types.h>
#include <mach/mach_init.h>
#include <mach/mach_host.h>

int main(int argc, const char * argv[]) {
    vm_size_t page_size;
    mach_port_t mach_port;
    mach_msg_type_number_t count;
    vm_statistics64_data_t vm_stats;

    mach_port = mach_host_self();
    count = sizeof(vm_stats) / sizeof(natural_t);
    if (KERN_SUCCESS == host_page_size(mach_port, &page_size) &&
        KERN_SUCCESS == host_statistics64(mach_port, HOST_VM_INFO,
                                        (host_info64_t)&vm_stats, &count))
    {
        long long free_memory = (int64_t)vm_stats.free_count * (int64_t)page_size;

        long long used_memory = ((int64_t)vm_stats.active_count +
                                 (int64_t)vm_stats.inactive_count +
                                 (int64_t)vm_stats.wire_count) *  (int64_t)page_size;
        printf("free memory: %lld\nused memory: %lld\n", free_memory, used_memory);
    }

    return 0;
}

For GPU usage you can use NVIDIA's Cuda Toolkit

In Particular for Mac -

#include <stdlib.h>
#include <iostream>
#include <iomanip>
#include <cuda_runtime_api.h>

#define CUDA_CALL(function, ...)  { \
    cudaError_t status = function(__VA_ARGS__); \
    anyCheck(status == cudaSuccess, cudaGetErrorString(status), #function, __FILE__, __LINE__); \
}

void anyCheck(bool is_ok, const char *description, const char *function, const char *file, int line) {
    if (!is_ok) {
        std::cout << "Error: " << description << " in " << function << " at " << file << ":" << line << std::endl;
        exit(EXIT_FAILURE);
    }
}

int main() {
    int cudaDeviceCount;
    struct cudaDeviceProp deviceProp;
    size_t memFree, memTotal;

    CUDA_CALL(cudaGetDeviceCount, &cudaDeviceCount);

    for (int deviceId = 0; deviceId < cudaDeviceCount; ++deviceId) {
        CUDA_CALL(cudaSetDevice, deviceId);
        CUDA_CALL(cudaGetDeviceProperties, &deviceProp, deviceId);

        //std::cout.imbue(std::locale("en_US.utf8"));
        std::cout << "Device " << deviceId;
        std::cout << " [PCIe " << deviceProp.pciDomainID << ":" << deviceProp.pciBusID
                  << ":" << deviceProp.pciDeviceID << ".0]";
        std::cout << ": " << deviceProp.name << " (CC " << deviceProp.major << "." << deviceProp.minor << ")";
        CUDA_CALL(cudaMemGetInfo, &memFree, &memTotal);
        std::cout << ": " << std::setprecision(5) << memFree/(1024*1024.) 
                  << " of " << memTotal/(1024*1024.) << " MB (i.e. "
                  << std::setprecision(3) << 100*memFree/(float)memTotal << "%) Free"
                  << std::endl;
    }
    return 0;
}

Ref- cuda-smi for mac

Hello-World
  • 72
  • 10
  • 1
    While these link may answer the question, it is better to include the essential parts of the answer here and provide the links for reference. Link-only answers can become invalid if the linked pages change. – Donald Duck Aug 30 '21 at 14:03
  • Please add further details to expand on your answer, such as working code or documentation citations. – Community Aug 30 '21 at 22:15