Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
LimaGroup
Lima
Commits
150f7cd7
Commit
150f7cd7
authored
Jul 19, 2021
by
Alejandro Homs Puron
Committed by
Generic Bliss account for Control Software
Apr 08, 2022
Browse files
Numa: add NumaNodeMask helper class, used by NumaAllocator
parent
bfaeb3f9
Pipeline
#71862
failed with stages
in 7 minutes and 57 seconds
Changes
4
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
common/include/lima/MemUtils.h
View file @
150f7cd7
...
...
@@ -149,15 +149,51 @@ protected:
#endif //__unix
#ifdef LIMA_USE_NUMA
class
LIMACORE_API
NumaAllocator
:
public
MMapAllocator
// Structure needed to bind memory to one or more CPU sockets
class
NumaNodeMask
{
public:
static
constexpr
int
MaxNbCPUs
=
128
;
typedef
std
::
bitset
<
MaxNbCPUs
>
Mask
;
typedef
std
::
bitset
<
MaxNbCPUs
>
CPUMask
;
typedef
std
::
vector
<
unsigned
long
>
ItemArray
;
static
constexpr
int
ItemBits
=
sizeof
(
ItemArray
::
value_type
)
*
8
;
NumaNodeMask
();
NumaNodeMask
(
const
ItemArray
&
array
);
NumaNodeMask
(
const
NumaNodeMask
&
o
);
NumaNodeMask
(
NumaNodeMask
&&
o
);
NumaNodeMask
&
operator
=
(
const
ItemArray
&
array
);
NumaNodeMask
&
operator
=
(
const
NumaNodeMask
&
o
);
NumaNodeMask
&
operator
=
(
NumaNodeMask
&&
o
);
static
int
getMaxNodes
();
static
int
getNbItems
();
static
NumaNodeMask
fromCPUMask
(
const
CPUMask
&
cpu_mask
);
void
bind
(
void
*
ptr
,
size_t
size
);
const
ItemArray
&
getArray
()
const
{
return
m_array
;
}
private:
const
ItemArray
&
checkArray
(
const
ItemArray
&
array
);
ItemArray
m_array
;
};
NumaAllocator
(
const
Mask
&
cpu_mask
)
:
m_cpu_mask
(
cpu_
mask
)
{}
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
const
NumaNodeMask
&
mask
)
;
const
Mask
&
getCPUAffinityMask
()
class
LIMACORE_API
NumaAllocator
:
public
MMapAllocator
{
public:
static
constexpr
int
MaxNbCPUs
=
NumaNodeMask
::
MaxNbCPUs
;
typedef
NumaNodeMask
::
CPUMask
CPUMask
;
NumaAllocator
(
const
CPUMask
&
cpu_mask
)
:
m_cpu_mask
(
cpu_mask
)
{}
const
CPUMask
&
getCPUAffinityMask
()
{
return
m_cpu_mask
;
}
// Allocate a buffer and sets the NUMA memory policy with mbind
...
...
@@ -165,13 +201,7 @@ public:
override
;
private:
// Given a cpu_mask, returns the memory node mask
// used by alloc to bind memory with the proper socket
void
getNUMANodeMask
(
const
Mask
&
cpu_mask
,
unsigned
long
&
node_mask
,
int
&
max_node
);
Mask
m_cpu_mask
;
//<! if NUMA is used, keep the cpu_mask for later use
CPUMask
m_cpu_mask
;
//<! if NUMA is used, keep cpu_mask for later use
};
#endif
...
...
common/src/MemUtils.cpp
View file @
150f7cd7
...
...
@@ -23,6 +23,7 @@
#include
<cstdlib>
#include
<sstream>
#include
<iomanip>
#ifdef __unix
#include
<sys/sysinfo.h>
#ifdef LIMA_USE_NUMA
...
...
@@ -301,37 +302,107 @@ void MemBuffer::deepCopy(const MemBuffer& buffer)
#ifdef LIMA_USE_NUMA
Allocator
::
DataPtr
NumaAllocator
::
alloc
(
void
*
&
ptr
,
size_t
&
size
,
size_t
alignment
)
int
NumaNodeMask
::
getMaxNodes
()
{
DataPtr
alloc_data
=
MMapAllocator
::
alloc
(
ptr
,
size
,
alignment
);
static
int
max_nb_nodes
=
numa_max_node
()
+
1
;
return
max_nb_nodes
;
}
if
(
m_cpu_mask
.
none
())
return
alloc_data
;
int
NumaNodeMask
::
getNbItems
()
{
return
(
getMaxNodes
()
-
1
)
/
ItemBits
+
1
;
}
unsigned
long
node_mask
;
int
max_node
;
getNUMANodeMask
(
m_cpu_mask
,
node_mask
,
max_node
);
if
(
mbind
(
ptr
,
size
,
MPOL_BIND
,
&
node_mask
,
max_node
,
0
)
!=
0
)
throw
LIMA_COM_EXC
(
Error
,
"Error in mbind: "
)
<<
strerror
(
errno
);
inline
const
NumaNodeMask
::
ItemArray
&
NumaNodeMask
::
checkArray
(
const
ItemArray
&
array
)
{
if
(
array
.
size
()
!=
getNbItems
())
throw
LIMA_COM_EXC
(
Error
,
"NumaNodeMask array has bad size"
);
return
array
;
}
return
alloc_data
;
NumaNodeMask
::
NumaNodeMask
()
:
m_array
(
getNbItems
(),
0
)
{}
NumaNodeMask
::
NumaNodeMask
(
const
ItemArray
&
array
)
:
m_array
(
checkArray
(
array
))
{}
NumaNodeMask
::
NumaNodeMask
(
const
NumaNodeMask
&
o
)
:
m_array
(
o
.
m_array
)
{}
NumaNodeMask
::
NumaNodeMask
(
NumaNodeMask
&&
o
)
:
m_array
(
std
::
move
(
o
.
m_array
))
{}
NumaNodeMask
&
NumaNodeMask
::
operator
=
(
const
ItemArray
&
array
)
{
m_array
=
checkArray
(
array
);
return
*
this
;
}
NumaNodeMask
&
NumaNodeMask
::
operator
=
(
const
NumaNodeMask
&
o
)
{
m_array
=
o
.
m_array
;
return
*
this
;
}
void
NumaAllocator
::
getNUMANodeMask
(
const
Mask
&
cpu_mask
,
unsigned
long
&
node_mask
,
int
&
max_node
)
NumaNodeMask
&
NumaNodeMask
::
operator
=
(
NumaNodeMask
&&
o
)
{
int
nb_nodes
=
numa_max_node
()
+
1
;
max_node
=
nb_nodes
+
1
;
m_array
=
std
::
move
(
o
.
m_array
);
return
*
this
;
}
NumaNodeMask
NumaNodeMask
::
fromCPUMask
(
const
CPUMask
&
cpu_mask
)
{
typedef
std
::
list
<
std
::
pair
<
CPUMask
,
NumaNodeMask
>>
NumaNodeList
;
static
NumaNodeList
cpu_numa_node_list
;
NumaNodeList
::
iterator
it
,
end
=
cpu_numa_node_list
.
end
();
for
(
it
=
cpu_numa_node_list
.
begin
();
it
!=
end
;
++
it
)
if
(
it
->
first
==
cpu_mask
)
return
it
->
second
;;
NumaNodeMask
numa_node_mask
;
ItemArray
&
node_mask
=
numa_node_mask
.
m_array
;
node_mask
=
0
;
for
(
unsigned
int
i
=
0
;
i
<
MaxNbCPUs
;
++
i
)
{
if
(
cpu_mask
.
test
(
i
))
{
unsigned
int
n
=
numa_node_of_cpu
(
i
);
node_mask
|=
1L
<<
n
;
if
(
n
>=
getMaxNodes
())
throw
LIMA_COM_EXC
(
Error
,
"Numa node too high"
);
node_mask
[
n
/
ItemBits
]
|=
1L
<<
(
n
%
ItemBits
);
}
}
cpu_numa_node_list
.
emplace_back
(
std
::
make_pair
(
cpu_mask
,
node_mask
));
return
numa_node_mask
;
}
void
NumaNodeMask
::
bind
(
void
*
ptr
,
size_t
size
)
{
int
max_node
=
getMaxNodes
()
+
1
;
// Linux kernel decrements max_node(?)
if
(
mbind
(
ptr
,
size
,
MPOL_BIND
,
&
m_array
[
0
],
max_node
,
0
)
!=
0
)
throw
LIMA_COM_EXC
(
Error
,
"Error in mbind: "
)
<<
strerror
(
errno
);
}
std
::
ostream
&
lima
::
operator
<<
(
std
::
ostream
&
os
,
const
NumaNodeMask
&
mask
)
{
os
<<
"["
<<
mask
.
getMaxNodes
()
<<
"-bit]"
<<
hex
<<
setfill
(
'0'
);
bool
first
=
true
;
int
missaligned_bits
=
mask
.
getMaxNodes
()
%
mask
.
ItemBits
;
int
first_bits
=
missaligned_bits
?
missaligned_bits
:
mask
.
ItemBits
;
const
NumaNodeMask
::
ItemArray
&
array
=
mask
.
getArray
();
NumaNodeMask
::
ItemArray
::
const_reverse_iterator
it
,
end
=
array
.
rend
();
for
(
it
=
array
.
rbegin
();
it
!=
end
;
++
it
,
first
=
false
)
{
int
word_bits
=
first
?
first_bits
:
mask
.
ItemBits
;
os
<<
(
!
first
?
","
:
""
)
<<
setw
(
word_bits
/
4
)
<<
*
it
;
}
return
os
<<
setfill
(
' '
)
<<
dec
;
}
Allocator
::
DataPtr
NumaAllocator
::
alloc
(
void
*
&
ptr
,
size_t
&
size
,
size_t
alignment
)
{
DataPtr
alloc_data
=
MMapAllocator
::
alloc
(
ptr
,
size
,
alignment
);
if
(
m_cpu_mask
.
none
())
return
alloc_data
;
NumaNodeMask
node_mask
=
NumaNodeMask
::
fromCPUMask
(
m_cpu_mask
);
node_mask
.
bind
(
ptr
,
size
);
return
alloc_data
;
}
#endif //LIMA_USE_NUMA
hardware/include/lima/HwBufferMgr.h
View file @
150f7cd7
...
...
@@ -111,12 +111,12 @@ class LIMACORE_API NumaSoftBufferAllocMgr : public SoftBufferAllocMgr
public:
static
constexpr
int
MaxNbCPUs
=
NumaAllocator
::
MaxNbCPUs
;
typedef
NumaAllocator
::
Mask
Mask
;
typedef
NumaAllocator
::
CPU
Mask
CPU
Mask
;
NumaSoftBufferAllocMgr
();
virtual
~
NumaSoftBufferAllocMgr
();
void
setCPUAffinityMask
(
const
Mask
&
mask
);
void
setCPUAffinityMask
(
const
CPU
Mask
&
mask
);
protected:
NumaAllocator
*
m_numa_allocator
;
...
...
@@ -386,7 +386,7 @@ protected:
class
LIMACORE_API
NumaSoftBufferCtrlObj
:
public
SoftBufferCtrlObj
{
public:
typedef
NumaSoftBufferAllocMgr
::
Mask
Mask
;
typedef
NumaSoftBufferAllocMgr
::
CPU
Mask
CPU
Mask
;
NumaSoftBufferCtrlObj
()
:
SoftBufferCtrlObj
(
new
NumaSoftBufferAllocMgr
())
...
...
@@ -394,7 +394,7 @@ public:
virtual
~
NumaSoftBufferCtrlObj
()
=
default
;
void
setCPUAffinityMask
(
Mask
mask
)
void
setCPUAffinityMask
(
CPU
Mask
mask
)
{
NumaSoftBufferAllocMgr
*
mgr
;
mgr
=
static_cast
<
NumaSoftBufferAllocMgr
*>
(
m_buffer_alloc_mgr
.
getPtr
());
...
...
hardware/src/HwBufferMgr.cpp
View file @
150f7cd7
...
...
@@ -190,17 +190,17 @@ NumaSoftBufferAllocMgr::~NumaSoftBufferAllocMgr()
setAllocator
(
Allocator
::
defaultAllocator
());
}
void
NumaSoftBufferAllocMgr
::
setCPUAffinityMask
(
const
Mask
&
mask
)
void
NumaSoftBufferAllocMgr
::
setCPUAffinityMask
(
const
CPU
Mask
&
mask
)
{
DEB_MEMBER_FUNCT
();
if
(
DEB_CHECK_ANY
(
DebTypeParam
))
{
typedef
unsigned
long
ULong
;
constexpr
Mask
ULongMask
(
std
::
numeric_limits
<
ULong
>::
max
());
constexpr
CPU
Mask
ULongMask
(
std
::
numeric_limits
<
ULong
>::
max
());
std
::
ostringstream
os
;
typedef
unsigned
long
ULong
;
constexpr
int
NbULongBits
=
sizeof
(
ULong
)
*
8
;
for
(
int
i
=
0
;
i
<
MaxNbCPUs
/
NbULongBits
;
++
i
)
{
Mask
m
=
(
mask
>>
(
i
*
NbULongBits
))
&
ULongMask
;
CPU
Mask
m
=
(
mask
>>
(
i
*
NbULongBits
))
&
ULongMask
;
ULong
val
=
m
.
to_ulong
();
os
<<
std
::
hex
<<
val
;
}
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment