From 55e12fb34b1a4f52c5283a897c4323888a440b10 Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 23 Aug 2019 20:19:55 +0700 Subject: [PATCH] Extended information about OpenCL devices. --- src/backend/common/common.cmake | 5 +- src/backend/common/misc/PciTopology.h | 62 +++++++++++++++++++++++ src/backend/opencl/OclBackend.cpp | 27 ++++++---- src/backend/opencl/wrappers/OclDevice.cpp | 30 +++++++++++ src/backend/opencl/wrappers/OclDevice.h | 22 +++++--- 5 files changed, 125 insertions(+), 21 deletions(-) create mode 100644 src/backend/common/misc/PciTopology.h diff --git a/src/backend/common/common.cmake b/src/backend/common/common.cmake index c470ea50..ce7f3a27 100644 --- a/src/backend/common/common.cmake +++ b/src/backend/common/common.cmake @@ -1,13 +1,14 @@ set(HEADERS_BACKEND_COMMON + src/backend/common/Hashrate.h src/backend/common/interfaces/IBackend.h src/backend/common/interfaces/IThread.h src/backend/common/interfaces/IWorker.h - src/backend/common/Hashrate.h + src/backend/common/misc/PciTopology.h src/backend/common/Thread.h src/backend/common/Threads.h src/backend/common/Worker.h - src/backend/common/Workers.h src/backend/common/WorkerJob.h + src/backend/common/Workers.h ) set(SOURCES_BACKEND_COMMON diff --git a/src/backend/common/misc/PciTopology.h b/src/backend/common/misc/PciTopology.h new file mode 100644 index 00000000..dcfacb20 --- /dev/null +++ b/src/backend/common/misc/PciTopology.h @@ -0,0 +1,62 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2018 Lee Clagett + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef XMRIG_PCITOPOLOGY_H +#define XMRIG_PCITOPOLOGY_H + + +#include + + +#include "base/tools/String.h" + + +namespace xmrig { + + +class PciTopology +{ +public: + PciTopology() = default; + PciTopology(uint32_t bus, uint32_t device, uint32_t function) : bus(bus), device(device), function(function) {} + + uint32_t bus = 0; + uint32_t device = 0; + uint32_t function = 0; + + String toString() const + { + char *buf = new char[8](); + snprintf(buf, 8, "%02x:%02x.%01x", bus, device, function); + + return buf; + } +}; + + +} // namespace xmrig + + +#endif /* XMRIG_PCITOPOLOGY_H */ diff --git a/src/backend/opencl/OclBackend.cpp b/src/backend/opencl/OclBackend.cpp index b4616cb9..fd1bdfb5 100644 --- a/src/backend/opencl/OclBackend.cpp +++ b/src/backend/opencl/OclBackend.cpp @@ -121,22 +121,27 @@ public: Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") CYAN_BOLD("#%zu ") WHITE_BOLD("%s") "/" WHITE_BOLD("%s"), "OPENCL", platform.index(), platform.name().data(), platform.version().data()); for (const OclDevice &device : devices) { - char *name = nullptr; - if (device.board() == device.name()) { - const size_t size = device.name().size() + 64; - name = new char[size](); + const String topo = device.hasTopology() ? device.topology().toString() : "n/a"; + const size_t size = device.board().size() + device.name().size() + 64; + char *name = new char[size](); - snprintf(name, size, GREEN_BOLD("%s"), device.name().data()); + if (device.board() == device.name()) { + snprintf(name, size, GREEN_BOLD(" %s"), device.name().data()); } else { - const size_t size = device.board().size() + device.name().size() + 64; - name = new char[size](); - - snprintf(name, size, GREEN_BOLD("%s") " (" CYAN_BOLD("%s") ")", device.board().data(), device.name().data()); + snprintf(name, size, GREEN_BOLD(" %s") " (" CYAN_BOLD("%s") ")", device.board().data(), device.name().data()); } - Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") CYAN_BOLD("#%zu ") "%s cu:" WHITE_BOLD("%u") " mem:" CYAN("%1.2f/%1.2f") " GB", "OPENCL GPU", - device.index(), name, device.computeUnits(), static_cast(device.freeMem()) / oneGiB, static_cast(device.globalMem()) / oneGiB); + Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") CYAN_BOLD("#%zu") YELLOW(" %s") "%s " WHITE_BOLD("%uMHz") " cu:" WHITE_BOLD("%u") " mem:" CYAN("%1.2f/%1.2f") " GB", "OPENCL GPU", + device.index(), + topo.data(), + name, + device.clock(), + device.computeUnits(), + static_cast(device.freeMem()) / oneGiB, + static_cast(device.globalMem()) / oneGiB); + + delete [] name; } } diff --git a/src/backend/opencl/wrappers/OclDevice.cpp b/src/backend/opencl/wrappers/OclDevice.cpp index 75a8c694..c3908244 100644 --- a/src/backend/opencl/wrappers/OclDevice.cpp +++ b/src/backend/opencl/wrappers/OclDevice.cpp @@ -34,6 +34,13 @@ #include "rapidjson/document.h" +typedef union +{ + struct { cl_uint type; cl_uint data[5]; } raw; + struct { cl_uint type; cl_char unused[17]; cl_char bus; cl_char device; cl_char function; } pcie; +} topology_amd; + + namespace xmrig { @@ -112,6 +119,23 @@ xmrig::OclDevice::OclDevice(uint32_t index, cl_device_id id, cl_platform_id plat { m_vendorId = getVendorId(m_vendor); m_type = getType(m_name); + + if (m_vendorId == OCL_VENDOR_AMD) { + topology_amd topology; + + if (OclLib::getDeviceInfo(id, 0x4037 /* CL_DEVICE_TOPOLOGY_AMD */, sizeof(topology), &topology, nullptr) == CL_SUCCESS && topology.raw.type == 1) { + m_topology = true; + m_pciTopology = PciTopology(static_cast(topology.pcie.bus), static_cast(topology.pcie.device), static_cast(topology.pcie.function)); + } + } + else if (m_vendorId == OCL_VENDOR_NVIDIA) { + cl_uint bus = 0; + if (OclLib::getDeviceInfo(id, 0x4008 /* CL_DEVICE_PCI_BUS_ID_NV */, sizeof (bus), &bus, nullptr) == CL_SUCCESS) { + m_topology = true; + cl_uint slot = OclLib::getDeviceUint(id, 0x4009 /* CL_DEVICE_PCI_SLOT_ID_NV */); + m_pciTopology = PciTopology(bus, (slot >> 3) & 0xff, slot & 7); + } + } } @@ -127,6 +151,12 @@ size_t xmrig::OclDevice::globalMem() const } +uint32_t xmrig::OclDevice::clock() const +{ + return OclLib::getDeviceUint(id(), CL_DEVICE_MAX_CLOCK_FREQUENCY); +} + + void xmrig::OclDevice::generate(const Algorithm &algorithm, OclThreads &threads) const { uint32_t intensity = getIntensity(algorithm); diff --git a/src/backend/opencl/wrappers/OclDevice.h b/src/backend/opencl/wrappers/OclDevice.h index 15fdfc3c..fcedac85 100644 --- a/src/backend/opencl/wrappers/OclDevice.h +++ b/src/backend/opencl/wrappers/OclDevice.h @@ -29,6 +29,7 @@ #include +#include "backend/common/misc/PciTopology.h" #include "backend/opencl/wrappers/OclVendor.h" #include "base/tools/String.h" @@ -63,16 +64,19 @@ public: size_t freeMem() const; size_t globalMem() const; + uint32_t clock() const; void generate(const Algorithm &algorithm, OclThreads &threads) const; - inline bool isValid() const { return m_id != nullptr && m_platform != nullptr; } - inline cl_device_id id() const { return m_id; } - inline const String &board() const { return m_board.isNull() ? m_name : m_board; } - inline const String &name() const { return m_name; } - inline const String &vendor() const { return m_vendor; } - inline OclVendor vendorId() const { return m_vendorId; } - inline uint32_t computeUnits() const { return m_computeUnits; } - inline uint32_t index() const { return m_index; } + inline bool hasTopology() const { return m_topology; } + inline bool isValid() const { return m_id != nullptr && m_platform != nullptr; } + inline cl_device_id id() const { return m_id; } + inline const PciTopology &topology() const { return m_pciTopology; } + inline const String &board() const { return m_board.isNull() ? m_name : m_board; } + inline const String &name() const { return m_name; } + inline const String &vendor() const { return m_vendor; } + inline OclVendor vendorId() const { return m_vendorId; } + inline uint32_t computeUnits() const { return m_computeUnits; } + inline uint32_t index() const { return m_index; } private: uint32_t getIntensity(const Algorithm &algorithm) const; @@ -82,6 +86,7 @@ private: uint32_t getStridedIndex(const Algorithm &algorithm) const; uint32_t getWorksize(const Algorithm &algorithm) const; + bool m_topology = false; cl_device_id m_id = nullptr; cl_platform_id m_platform = nullptr; const String m_board; @@ -90,6 +95,7 @@ private: const uint32_t m_computeUnits = 1; const uint32_t m_index = 0; OclVendor m_vendorId = OCL_VENDOR_UNKNOWN; + PciTopology m_pciTopology; Type m_type = Unknown; };