Arcane  v4.1.0.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/common/DefaultMemoryAllocator.h"
20#include "arccore/common/AlignedMemoryAllocator.h"
21#include "arccore/common/AllocatedMemoryInfo.h"
22
23#include <cstdlib>
24#include <cstring>
25#include <errno.h>
26
27#if defined(ARCCORE_OS_WIN32)
28#include <malloc.h>
29#endif
30
31#include <iostream>
32
33#if defined(ARCCORE_OS_LINUX) || defined(ARCCORE_OS_MACOS)
34#define ARCCORE_USE_POSIX_MEMALIGN
35#endif
36
37/*---------------------------------------------------------------------------*/
38/*---------------------------------------------------------------------------*/
39
40namespace Arcane
41{
42
43/*---------------------------------------------------------------------------*/
44/*---------------------------------------------------------------------------*/
45
46DefaultMemoryAllocator DefaultMemoryAllocator::shared_null_instance;
47
48/*---------------------------------------------------------------------------*/
49/*---------------------------------------------------------------------------*/
50
53{
54 return this->guaranteedAlignment(args);
55}
56
57/*---------------------------------------------------------------------------*/
58/*---------------------------------------------------------------------------*/
59
64
65/*---------------------------------------------------------------------------*/
66/*---------------------------------------------------------------------------*/
67
69copyMemory([[maybe_unused]] MemoryAllocationArgs args, AllocatedMemoryInfo destination,
71{
72 std::memcpy(destination.baseAddress(), source.baseAddress(), source.size());
73}
74
75/*---------------------------------------------------------------------------*/
76/*---------------------------------------------------------------------------*/
77
78/*---------------------------------------------------------------------------*/
79/*---------------------------------------------------------------------------*/
80
83{
84 return true;
85}
86
87/*---------------------------------------------------------------------------*/
88/*---------------------------------------------------------------------------*/
89
92{
93 return { ::malloc(new_size), new_size };
94}
95
96/*---------------------------------------------------------------------------*/
97/*---------------------------------------------------------------------------*/
98
101{
102 return { ::realloc(current_ptr.baseAddress(), new_size), new_size };
103}
104
105/*---------------------------------------------------------------------------*/
106/*---------------------------------------------------------------------------*/
107
113
114/*---------------------------------------------------------------------------*/
115/*---------------------------------------------------------------------------*/
116
118adjustedCapacity(MemoryAllocationArgs, Int64 wanted_capacity, Int64 ) const
119{
120 return wanted_capacity;
121}
122
123/*---------------------------------------------------------------------------*/
124/*---------------------------------------------------------------------------*/
125
126/*---------------------------------------------------------------------------*/
127/*---------------------------------------------------------------------------*/
128
129AlignedMemoryAllocator AlignedMemoryAllocator::
131
132AlignedMemoryAllocator AlignedMemoryAllocator::
134
135/*---------------------------------------------------------------------------*/
136/*---------------------------------------------------------------------------*/
142
143/*---------------------------------------------------------------------------*/
144/*---------------------------------------------------------------------------*/
145
147allocate([[maybe_unused]] MemoryAllocationArgs args, Int64 new_size)
148{
149#if defined(ARCCORE_USE_POSIX_MEMALIGN)
150 void* ptr = nullptr;
151 int e = ::posix_memalign(&ptr, m_alignment, new_size);
152 if (e == EINVAL)
153 throw ArgumentException(A_FUNCINFO, "Invalid argument to posix_memalign");
154 if (e == ENOMEM)
155 return AllocatedMemoryInfo(nullptr);
156 return AllocatedMemoryInfo(ptr, new_size);
157#elif defined(ARCCORE_OS_WIN32)
158 return AllocatedMemoryInfo(_aligned_malloc(new_size, m_alignment), new_size);
159#else
160 throw NotImplementedException(A_FUNCINFO);
161#endif
162}
163
164/*---------------------------------------------------------------------------*/
165/*---------------------------------------------------------------------------*/
166
168reallocate([[maybe_unused]] MemoryAllocationArgs args, AllocatedMemoryInfo current_ptr, Int64 new_size)
169{
170#if defined(ARCCORE_USE_POSIX_MEMALIGN)
171 ARCCORE_UNUSED(current_ptr);
172 ARCCORE_UNUSED(new_size);
173 throw NotSupportedException(A_FUNCINFO);
174#elif defined(ARCCORE_OS_WIN32)
175 return AllocatedMemoryInfo(_aligned_realloc(current_ptr.baseAddress(), new_size, m_alignment), new_size);
176#else
177 throw NotImplementedException(A_FUNCINFO);
178#endif
179}
180
181/*---------------------------------------------------------------------------*/
182/*---------------------------------------------------------------------------*/
183
185deallocate([[maybe_unused]] MemoryAllocationArgs args, AllocatedMemoryInfo ptr)
186{
187#if defined(ARCCORE_USE_POSIX_MEMALIGN)
188 ::free(ptr.baseAddress());
189#elif defined(ARCCORE_OS_WIN32)
190 return _aligned_free(ptr.baseAddress());
191#else
192 throw NotImplementedException(A_FUNCINFO);
193#endif
194}
195
196/*---------------------------------------------------------------------------*/
197/*---------------------------------------------------------------------------*/
198
199namespace
200{
201 bool is_verbose = false;
202}
203
204size_t
205adjustMemoryCapacity(size_t wanted_capacity, size_t element_size, size_t alignment)
206{
207 if (element_size == 0)
208 return wanted_capacity;
209 // Si \a element_size est plus petit que \a m_alignment, considère que
210 // la mémoire allouée doit être un multiple de l'alignement.
211 // (On pourrait être plus restrictif suivant les types mais ce n'est en
212 // général pas utile).
213 size_t block_size = alignment / element_size;
214 if (block_size <= 1)
215 return wanted_capacity;
216
217 // Si l'alignement n'est pas un multiple de la taille d'un élément,
218 // cela signifie que l'élément ne sera pas utilisé pour la vectorisation.
219 // Il n'est donc pas nécessaire dans ce cas de modifier la capacité.
220 size_t nb_element = alignment % element_size;
221 if (nb_element != 0)
222 return wanted_capacity;
223
224 if (is_verbose)
225 std::cout << " wanted_capacity=" << wanted_capacity
226 << " element_size=" << element_size
227 << " block_size=" << block_size << '\n';
228
229 // Ajoute à la capacité ce qu'il faut pour que le module soit 0.
230 size_t modulo = wanted_capacity % block_size;
231 if (modulo != 0)
232 wanted_capacity += (block_size - modulo);
233 if (is_verbose)
234 std::cout << " final_wanted_capacity=" << wanted_capacity
235 << " modulo=" << modulo << '\n';
236 ARCCORE_ASSERT(((wanted_capacity % block_size) == 0), ("Bad capacity"));
237 return wanted_capacity;
238}
239
240/*---------------------------------------------------------------------------*/
241/*---------------------------------------------------------------------------*/
242
244adjustedCapacity([[maybe_unused]] MemoryAllocationArgs args, Int64 wanted_capacity, Int64 element_size) const
245{
246 return adjustMemoryCapacity(wanted_capacity, element_size, m_alignment);
247}
248
249/*---------------------------------------------------------------------------*/
250/*---------------------------------------------------------------------------*/
251
252/*---------------------------------------------------------------------------*/
253/*---------------------------------------------------------------------------*/
254
256allocate(MemoryAllocationArgs args, Int64 new_size)
257{
258 AllocatedMemoryInfo mem_info = Base::allocate(args, new_size);
259 std::cout << "DEF_ARRAY_ALLOCATE new_size=" << new_size << " ptr=" << mem_info.baseAddress() << '\n';
260 return mem_info;
261}
262
263/*---------------------------------------------------------------------------*/
264/*---------------------------------------------------------------------------*/
265
267reallocate(MemoryAllocationArgs args, AllocatedMemoryInfo current_ptr, Int64 new_size)
268{
269 AllocatedMemoryInfo mem_info = Base::reallocate(args, current_ptr, new_size);
270 std::cout << "DEF_ARRAY_REALLOCATE new_size=" << new_size
271 << " current_ptr=" << current_ptr.baseAddress()
272 << " new_ptr=" << mem_info.baseAddress() << '\n';
273 return mem_info;
274}
275
276/*---------------------------------------------------------------------------*/
277/*---------------------------------------------------------------------------*/
278
281{
282 std::cout << "DEF_ARRAY_DEALLOCATE ptr=" << ptr.baseAddress() << '\n';
283 Base::deallocate(args, ptr);
284}
285
286/*---------------------------------------------------------------------------*/
287/*---------------------------------------------------------------------------*/
288
289} // namespace Arccore
290
291/*---------------------------------------------------------------------------*/
292/*---------------------------------------------------------------------------*/
Allocateur mémoire avec alignement mémoire spécifique.
AllocatedMemoryInfo allocate(MemoryAllocationArgs args, Int64 new_size) override
static constexpr Integer simdAlignment()
Alignement pour les structures utilisant la vectorisation.
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.
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 cacheLineAlignment()
Alignement pour une ligne de cache.
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.
Allocateur mémoire via malloc/realloc/free.
void deallocate(MemoryAllocationArgs, AllocatedMemoryInfo ptr) override
Libère la mémoire dont l'adresse de base est ptr.
AllocatedMemoryInfo reallocate(MemoryAllocationArgs, AllocatedMemoryInfo current_ptr, Int64 new_size) override
Ré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 allocate(MemoryAllocationArgs, Int64 new_size) override
Alloue de la mémoire pour new_size octets et retourne le pointeur.
bool hasRealloc(MemoryAllocationArgs) const override
Indique si l'allocateur supporte la sémantique de realloc.
virtual void copyMemory(MemoryAllocationArgs args, AllocatedMemoryInfo destination, AllocatedMemoryInfo source)
Copie la mémoire entre deux zones.
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.
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 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.
AllocatedMemoryInfo allocate(MemoryAllocationArgs args, Int64 new_size) override
Alloue de la mémoire pour new_size octets et retourne le pointeur.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
std::int64_t Int64
Type entier signé sur 64 bits.