14#include "arcane/utils/IProcessorAffinityService.h"
15#include "arcane/utils/ITraceMng.h"
16#include "arcane/utils/OStringStream.h"
18#include "arcane/core/FactoryService.h"
19#include "arcane/core/AbstractService.h"
21#include "arccore/base/internal/DependencyInjection.h"
36class HWLocProcessorAffinityService
46 explicit HWLocProcessorAffinityService(
ITraceMng* tm)
52 ~HWLocProcessorAffinityService()
override
55 hwloc_topology_destroy(m_topology);
60 void build()
override {}
75 bool m_is_init =
false;
76 hwloc_topology_t m_topology =
nullptr;
81 void _outputTopology(hwloc_obj_t l, hwloc_obj_t parent,
int i,
OStringStream& ostr);
82 int _numberOf(
const hwloc_obj_type_t);
90_internal_hwloc_obj_snprintf(
char*
string,
size_t size,
91 hwloc_obj* l,
const char* _indexprefix,
int verbose)
93 const char* indexprefix = _indexprefix ? _indexprefix :
"#";
94 char os_index[12] =
"";
99 if (l->os_index != (
unsigned)-1) {
100 std::snprintf(os_index, 12,
"%s%u", indexprefix, l->os_index);
103 hwloc_obj_type_snprintf(type,
sizeof(type), l, verbose);
104 attrlen = hwloc_obj_attr_snprintf(attr,
sizeof(attr), l,
" ", verbose);
107 return std::snprintf(
string, size,
"%s%s(%s)", type, os_index, attr);
109 return std::snprintf(
string, size,
"%s%s", type, os_index);
116void HWLocProcessorAffinityService::
117_outputTopology(hwloc_obj_t l, hwloc_obj_t parent,
int i,
OStringStream& ostr)
119 const char* indexprefix =
"#";
121 if (parent && parent->arity == 1 && hwloc_bitmap_isequal(l->cpuset, parent->cpuset)) {
126 info() << ostr.str();
129 for (
int z = 0; z < 2 * i; ++z)
133 _internal_hwloc_obj_snprintf(line,
sizeof(line) - 1, l, indexprefix, 0);
135 unsigned int arity = l->arity;
136 if (arity != 0 || (!i && !arity)) {
137 for (
unsigned int x = 0; x < arity; ++x) {
138 _outputTopology(l->children[x], l, i, ostr);
146void HWLocProcessorAffinityService::
153 info() <<
"Getting hardware architecture hwloc_version=" << HWLOC_VERSION;
154 int err = hwloc_topology_init(&m_topology);
156 info() <<
"Error in hwloc_topology_init r=" << err;
159 unsigned long flags = 0;
160 hwloc_topology_set_flags(m_topology, flags);
162 err = hwloc_topology_load(m_topology);
164 info() <<
"Error in hwloc_topology_load r=" << err;
175 hwloc_bitmap_t new_cpuset = hwloc_bitmap_alloc();
176 hwloc_get_cpubind(m_topology, new_cpuset, 0 | HWLOC_CPUBIND_THREAD);
178 hwloc_bitmap_snprintf(result_s,
sizeof(result_s) - 1, new_cpuset);
181 hwloc_bitmap_free(new_cpuset);
193 _outputTopology(hwloc_get_root_obj(m_topology),
nullptr, 0, ostrf);
194 info() << ostrf.str();
205 hwloc_bitmap_t new_cpuset = hwloc_bitmap_alloc();
206 hwloc_get_cpubind(m_topology, new_cpuset, 0 | HWLOC_CPUBIND_THREAD);
210 unsigned int cpu_iter = 0;
211 hwloc_bitmap_foreach_begin(cpu_iter, new_cpuset)
215 if (cpu_index == cpu)
216 hwloc_bitmap_only(new_cpuset, cpu_iter);
219 hwloc_bitmap_foreach_end();
222 hwloc_set_cpubind(m_topology, new_cpuset, flags | HWLOC_CPUBIND_THREAD);
225 hwloc_get_cpubind(m_topology, new_cpuset, 0 | HWLOC_CPUBIND_THREAD);
227 hwloc_bitmap_snprintf(result_s,
sizeof(result_s) - 1, new_cpuset);
229 hwloc_bitmap_free(new_cpuset);
235Int32 HWLocProcessorAffinityService::
236_numberOf(
const hwloc_obj_type_t that)
239 int depth = hwloc_get_type_depth(m_topology, that);
240 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN)
242 int width = hwloc_get_nbobjs_by_depth(m_topology, depth);
252 return _numberOf(HWLOC_OBJ_CORE);
261 return _numberOf(HWLOC_OBJ_SOCKET);
270 return _numberOf(HWLOC_OBJ_PU);
284 DependencyInjection::ProviderProperty(
"HWLoc"),
#define ARCANE_REGISTER_APPLICATION_FACTORY(aclass, ainterface, aname)
Enregistre un service de fabrique pour la classe aclass.
Int32 numberOfProcessingUnit() override
Nombre de coeurs logiques (-1 si inconnu)
void bindThread(Int32 cpu) override
Contraint le thread courant à rester sur le coeur d'indice cpu.
void printInfos() override
Affiche les informations complète de topologie via info()
Int32 numberOfCore() override
Nombre de coeurs CPU (-1 si inconnu)
String cpuSetString() override
Retourne le cpuset pour le thread courant.
Int32 numberOfSocket() override
Nombre de sockets (-1 si inconnu)
virtual ITraceMng * traceMng() const =0
Gestionnaire de traces.
Interface d'un service de gestion de l'affinité des coeurs CPU.
Interface du gestionnaire de traces.
Flot de sortie lié à une String.
IApplication * application() const
Accès à l'application IApplication associé.
Structure contenant les informations pour créer un service.
Vue sur une chaîne de caractères UTF-8.
Chaîne de caractères unicode.
TraceAccessor(ITraceMng *m)
Construit un accesseur via le gestionnaire de trace m.
TraceMessage info() const
Flot pour un message d'information.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
Int32 Integer
Type représentant un entier.
std::int32_t Int32
Type entier signé sur 32 bits.