Arcane  v3.15.3.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
MemoryAllocator.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2025 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/* MemoryAllocator.cc (C) 2000-2025 */
9/* */
10/* Allocateurs mémoires. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arccore/base/ArgumentException.h"
15#include "arccore/base/NotSupportedException.h"
16#include "arccore/base/NotImplementedException.h"
17#include "arccore/base/TraceInfo.h"
18
19#include "arccore/collections/IMemoryAllocator.h"
20
21#include <cstdlib>
22#include <cstring>
23#include <errno.h>
24
25#if defined(ARCCORE_OS_WIN32)
26#include <malloc.h>
27#endif
28
29#include <iostream>
30
31#if defined(ARCCORE_OS_LINUX) || defined(ARCCORE_OS_MACOS)
32#define ARCCORE_USE_POSIX_MEMALIGN
33#endif
34
35/*---------------------------------------------------------------------------*/
36/*---------------------------------------------------------------------------*/
37
38namespace Arccore
39{
40
41/*---------------------------------------------------------------------------*/
42/*---------------------------------------------------------------------------*/
43
44DefaultMemoryAllocator DefaultMemoryAllocator::shared_null_instance;
45
46/*---------------------------------------------------------------------------*/
47/*---------------------------------------------------------------------------*/
48
51{
52 return this->guaranteedAlignment(args);
53}
54
55/*---------------------------------------------------------------------------*/
56/*---------------------------------------------------------------------------*/
57
62
63/*---------------------------------------------------------------------------*/
64/*---------------------------------------------------------------------------*/
65
67copyMemory([[maybe_unused]] MemoryAllocationArgs args, AllocatedMemoryInfo destination,
69{
70 std::memcpy(destination.baseAddress(), source.baseAddress(), source.size());
71}
72
73/*---------------------------------------------------------------------------*/
74/*---------------------------------------------------------------------------*/
75
76/*---------------------------------------------------------------------------*/
77/*---------------------------------------------------------------------------*/
78
81{
82 return true;
83}
84
85/*---------------------------------------------------------------------------*/
86/*---------------------------------------------------------------------------*/
87
90{
91 return { ::malloc(new_size), new_size };
92}
93
94/*---------------------------------------------------------------------------*/
95/*---------------------------------------------------------------------------*/
96
99{
100 return { ::realloc(current_ptr.baseAddress(), new_size), new_size };
101}
102
103/*---------------------------------------------------------------------------*/
104/*---------------------------------------------------------------------------*/
105
111
112/*---------------------------------------------------------------------------*/
113/*---------------------------------------------------------------------------*/
114
116adjustedCapacity(MemoryAllocationArgs, Int64 wanted_capacity, Int64 ) const
117{
118 return wanted_capacity;
119}
120
121/*---------------------------------------------------------------------------*/
122/*---------------------------------------------------------------------------*/
123
124/*---------------------------------------------------------------------------*/
125/*---------------------------------------------------------------------------*/
126
127AlignedMemoryAllocator AlignedMemoryAllocator::
129
130AlignedMemoryAllocator AlignedMemoryAllocator::
132
133/*---------------------------------------------------------------------------*/
134/*---------------------------------------------------------------------------*/
141/*---------------------------------------------------------------------------*/
142/*---------------------------------------------------------------------------*/
143
145allocate([[maybe_unused]] MemoryAllocationArgs args, Int64 new_size)
146{
147#if defined(ARCCORE_USE_POSIX_MEMALIGN)
148 void* ptr = nullptr;
149 int e = ::posix_memalign(&ptr, m_alignment, new_size);
150 if (e == EINVAL)
151 throw ArgumentException(A_FUNCINFO, "Invalid argument to posix_memalign");
152 if (e == ENOMEM)
153 return AllocatedMemoryInfo(nullptr);
154 return AllocatedMemoryInfo(ptr, new_size);
155#elif defined(ARCCORE_OS_WIN32)
156 return AllocatedMemoryInfo(_aligned_malloc(new_size, m_alignment), new_size);
157#else
158 throw NotImplementedException(A_FUNCINFO);
159#endif
160}
161
162/*---------------------------------------------------------------------------*/
163/*---------------------------------------------------------------------------*/
164
166reallocate([[maybe_unused]] MemoryAllocationArgs args, AllocatedMemoryInfo current_ptr, Int64 new_size)
167{
168#if defined(ARCCORE_USE_POSIX_MEMALIGN)
169 ARCCORE_UNUSED(current_ptr);
170 ARCCORE_UNUSED(new_size);
171 throw NotSupportedException(A_FUNCINFO);
172#elif defined(ARCCORE_OS_WIN32)
173 return AllocatedMemoryInfo(_aligned_realloc(current_ptr.baseAddress(), new_size, m_alignment), new_size);
174#else
175 throw NotImplementedException(A_FUNCINFO);
176#endif
177}
178
179/*---------------------------------------------------------------------------*/
180/*---------------------------------------------------------------------------*/
181
183deallocate([[maybe_unused]] MemoryAllocationArgs args, AllocatedMemoryInfo ptr)
184{
185#if defined(ARCCORE_USE_POSIX_MEMALIGN)
186 ::free(ptr.baseAddress());
187#elif defined(ARCCORE_OS_WIN32)
188 return _aligned_free(ptr.baseAddress());
189#else
190 throw NotImplementedException(A_FUNCINFO);
191#endif
192}
193
194/*---------------------------------------------------------------------------*/
195/*---------------------------------------------------------------------------*/
196
197namespace
198{
199 bool is_verbose = false;
200}
201
202size_t
203adjustMemoryCapacity(size_t wanted_capacity, size_t element_size, size_t alignment)
204{
205 if (element_size == 0)
206 return wanted_capacity;
207 // Si \a element_size est plus petit que \a m_alignment, considère que
208 // la mémoire allouée doit être un multiple de l'alignement.
209 // (On pourrait être plus restrictif suivant les types mais ce n'est en
210 // général pas utile).
211 size_t block_size = alignment / element_size;
212 if (block_size <= 1)
213 return wanted_capacity;
214
215 // Si l'alignement n'est pas un multiple de la taille d'un élément,
216 // cela signifie que l'élément ne sera pas utilisé pour la vectorisation.
217 // Il n'est donc pas nécessaire dans ce cas de modifier la capacité.
218 size_t nb_element = alignment % element_size;
219 if (nb_element != 0)
220 return wanted_capacity;
221
222 if (is_verbose)
223 std::cout << " wanted_capacity=" << wanted_capacity
224 << " element_size=" << element_size
225 << " block_size=" << block_size << '\n';
226
227 // Ajoute à la capacité ce qu'il faut pour que le module soit 0.
228 size_t modulo = wanted_capacity % block_size;
229 if (modulo != 0)
230 wanted_capacity += (block_size - modulo);
231 if (is_verbose)
232 std::cout << " final_wanted_capacity=" << wanted_capacity
233 << " modulo=" << modulo << '\n';
234 ARCCORE_ASSERT(((wanted_capacity % block_size) == 0), ("Bad capacity"));
235 return wanted_capacity;
236}
237
238/*---------------------------------------------------------------------------*/
239/*---------------------------------------------------------------------------*/
240
242adjustedCapacity([[maybe_unused]] MemoryAllocationArgs args, Int64 wanted_capacity, Int64 element_size) const
243{
244 return adjustMemoryCapacity(wanted_capacity, element_size, m_alignment);
245}
246
247/*---------------------------------------------------------------------------*/
248/*---------------------------------------------------------------------------*/
249
250/*---------------------------------------------------------------------------*/
251/*---------------------------------------------------------------------------*/
252
254allocate(MemoryAllocationArgs args, Int64 new_size)
255{
256 AllocatedMemoryInfo mem_info = Base::allocate(args, new_size);
257 std::cout << "DEF_ARRAY_ALLOCATE new_size=" << new_size << " ptr=" << mem_info.baseAddress() << '\n';
258 return mem_info;
259}
260
261/*---------------------------------------------------------------------------*/
262/*---------------------------------------------------------------------------*/
263
265reallocate(MemoryAllocationArgs args, AllocatedMemoryInfo current_ptr, Int64 new_size)
266{
267 AllocatedMemoryInfo mem_info = Base::reallocate(args, current_ptr, new_size);
268 std::cout << "DEF_ARRAY_REALLOCATE new_size=" << new_size
269 << " current_ptr=" << current_ptr.baseAddress()
270 << " new_ptr=" << mem_info.baseAddress() << '\n';
271 return mem_info;
272}
273
274/*---------------------------------------------------------------------------*/
275/*---------------------------------------------------------------------------*/
276
279{
280 std::cout << "DEF_ARRAY_DEALLOCATE ptr=" << ptr.baseAddress() << '\n';
281 Base::deallocate(args, ptr);
282}
283
284/*---------------------------------------------------------------------------*/
285/*---------------------------------------------------------------------------*/
286
287} // namespace Arccore
288
289/*---------------------------------------------------------------------------*/
290/*---------------------------------------------------------------------------*/
Allocateur mémoire avec alignement mémoire spécifique.
AllocatedMemoryInfo reallocate(MemoryAllocationArgs args, AllocatedMemoryInfo current_ptr, Int64 new_size) override
Réalloue de la mémoire pour new_size octets et retourne le pointeur.
static constexpr Integer simdAlignment()
Alignement pour les structures utilisant la vectorisation.
static constexpr Integer cacheLineAlignment()
Alignement pour une ligne de cache.
AllocatedMemoryInfo allocate(MemoryAllocationArgs args, Int64 new_size) override
void deallocate(MemoryAllocationArgs args, AllocatedMemoryInfo ptr) override
Libère la mémoire dont l'adresse de base est ptr.
Int64 adjustedCapacity(MemoryAllocationArgs args, Int64 wanted_capacity, Int64 element_size) const override
Ajuste la capacité suivant la taille d'élément.
Informations sur une zone mémoire allouée.
void * baseAddress() const
Adresse du début de la zone allouée.
Exception lorsqu'un argument est invalide.
bool hasRealloc(MemoryAllocationArgs) const override
Indique si l'allocateur supporte la sémantique de realloc.
AllocatedMemoryInfo allocate(MemoryAllocationArgs, Int64 new_size) override
Alloue de la mémoire pour new_size octets et retourne le pointeur.
Int64 adjustedCapacity(MemoryAllocationArgs, Int64 wanted_capacity, Int64 element_size) const override
Ajuste la capacité suivant la taille d'élément.
AllocatedMemoryInfo reallocate(MemoryAllocationArgs, AllocatedMemoryInfo current_ptr, Int64 new_size) override
Réalloue de la mémoire pour new_size octets et retourne le pointeur.
void deallocate(MemoryAllocationArgs, AllocatedMemoryInfo ptr) override
Libère la mémoire dont l'adresse de base est ptr.
virtual void notifyMemoryArgsChanged(MemoryAllocationArgs old_args, MemoryAllocationArgs new_args, AllocatedMemoryInfo ptr)
Notifie du changement des arguments spécifiques à l'instance.
virtual size_t guarantedAlignment(MemoryAllocationArgs args) const
Valeur de l'alignement garanti par l'allocateur.
virtual size_t guaranteedAlignment(MemoryAllocationArgs args) const =0
Valeur de l'alignement garanti par l'allocateur.
virtual void copyMemory(MemoryAllocationArgs args, AllocatedMemoryInfo destination, AllocatedMemoryInfo source)
Copie la mémoire entre deux zones.
Classe contenant des informations pour spécialiser les allocations.
Exception lorsqu'une fonction n'est pas implémentée.
Exception lorsqu'une opération n'est pas supportée.
AllocatedMemoryInfo allocate(MemoryAllocationArgs args, Int64 new_size) override
Alloue de la mémoire pour new_size octets et retourne le pointeur.
AllocatedMemoryInfo reallocate(MemoryAllocationArgs args, AllocatedMemoryInfo current_ptr, Int64 new_size) override
Réalloue de la mémoire pour new_size octets et retourne le pointeur.
void deallocate(MemoryAllocationArgs args, AllocatedMemoryInfo ptr) override
Libère la mémoire dont l'adresse de base est ptr.
Espace de nom de Arccore.
Definition ArcaneTypes.h:29
std::int64_t Int64
Type entier signé sur 64 bits.