Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Questo documento illustra come usare le funzioni concurrency::Alloc e concurrency::Free per migliorare le prestazioni di memoria. Confronta il tempo necessario per invertire gli elementi di una matrice in parallelo per tre tipi diversi che ognuno specifica gli new operatori e delete .
Le Alloc funzioni e Free sono più utili quando più thread chiamano frequentemente sia Alloc che Free. Il runtime contiene una cache di memoria separata per ogni thread; pertanto, il runtime gestisce la memoria senza l'uso di blocchi o barriere di memoria.
Esempio: tipi che specificano operatori nuovi ed eliminati
Nell'esempio seguente vengono illustrati tre tipi che specificano gli new operatori e delete . La new_delete classe usa gli operatori globali new e delete , la malloc_free classe usa le funzioni malloc e free del runtime C e la Alloc_Free classe usa il runtime Alloc di concorrenza e Free le funzioni.
// A type that defines the new and delete operators. These operators
// call the global new and delete operators, respectively.
class new_delete
{
public:
static void* operator new(size_t size)
{
return ::operator new(size);
}
static void operator delete(void *p)
{
return ::operator delete(p);
}
int _data;
};
// A type that defines the new and delete operators. These operators
// call the C Runtime malloc and free functions, respectively.
class malloc_free
{
public:
static void* operator new(size_t size)
{
return malloc(size);
}
static void operator delete(void *p)
{
return free(p);
}
int _data;
};
// A type that defines the new and delete operators. These operators
// call the Concurrency Runtime Alloc and Free functions, respectively.
class Alloc_Free
{
public:
static void* operator new(size_t size)
{
return Alloc(size);
}
static void operator delete(void *p)
{
return Free(p);
}
int _data;
};
Esempio: funzioni swap e reverse_array
Nell'esempio seguente vengono illustrate le funzioni swap e reverse_array. La swap funzione scambia il contenuto della matrice in corrispondenza degli indici specificati. Alloca memoria dall'heap per la variabile temporanea. La reverse_array funzione crea una matrice di grandi dimensioni e calcola il tempo necessario per invertire la matrice più volte in parallelo.
// Exchanges the contents of a[index1] with a[index2].
template<class T>
void swap(T* a, int index1, int index2)
{
// For illustration, allocate memory from the heap.
// This is useful when sizeof(T) is large.
T* temp = new T;
*temp = a[index1];
a[index1] = a[index2];
a[index2] = *temp;
delete temp;
}
// Computes the time that it takes to reverse the elements of a
// large array of the specified type.
template <typename T>
__int64 reverse_array()
{
const int size = 5000000;
T* a = new T[size];
__int64 time = 0;
const int repeat = 11;
// Repeat the operation several times to amplify the time difference.
for (int i = 0; i < repeat; ++i)
{
time += time_call([&] {
parallel_for(0, size/2, [&](int index)
{
swap(a, index, size-index-1);
});
});
}
delete[] a;
return time;
}
Esempio: funzione wmain
Nell'esempio seguente viene illustrata la wmain funzione , che calcola il tempo necessario per la reverse_array funzione per agire sui new_deletetipi , malloc_freee Alloc_Free , ognuno dei quali usa uno schema di allocazione di memoria diverso.
int wmain()
{
// Compute the time that it takes to reverse large arrays of
// different types.
// new_delete
wcout << L"Took " << reverse_array<new_delete>()
<< " ms with new/delete." << endl;
// malloc_free
wcout << L"Took " << reverse_array<malloc_free>()
<< " ms with malloc/free." << endl;
// Alloc_Free
wcout << L"Took " << reverse_array<Alloc_Free>()
<< " ms with Alloc/Free." << endl;
}
Esempio di codice completo
L'esempio completo segue.
// allocators.cpp
// compile with: /EHsc
#include <windows.h>
#include <ppl.h>
#include <iostream>
using namespace concurrency;
using namespace std;
// Calls the provided work function and returns the number of milliseconds
// that it takes to call that function.
template <class Function>
__int64 time_call(Function&& f)
{
__int64 begin = GetTickCount();
f();
return GetTickCount() - begin;
}
// A type that defines the new and delete operators. These operators
// call the global new and delete operators, respectively.
class new_delete
{
public:
static void* operator new(size_t size)
{
return ::operator new(size);
}
static void operator delete(void *p)
{
return ::operator delete(p);
}
int _data;
};
// A type that defines the new and delete operators. These operators
// call the C Runtime malloc and free functions, respectively.
class malloc_free
{
public:
static void* operator new(size_t size)
{
return malloc(size);
}
static void operator delete(void *p)
{
return free(p);
}
int _data;
};
// A type that defines the new and delete operators. These operators
// call the Concurrency Runtime Alloc and Free functions, respectively.
class Alloc_Free
{
public:
static void* operator new(size_t size)
{
return Alloc(size);
}
static void operator delete(void *p)
{
return Free(p);
}
int _data;
};
// Exchanges the contents of a[index1] with a[index2].
template<class T>
void swap(T* a, int index1, int index2)
{
// For illustration, allocate memory from the heap.
// This is useful when sizeof(T) is large.
T* temp = new T;
*temp = a[index1];
a[index1] = a[index2];
a[index2] = *temp;
delete temp;
}
// Computes the time that it takes to reverse the elements of a
// large array of the specified type.
template <typename T>
__int64 reverse_array()
{
const int size = 5000000;
T* a = new T[size];
__int64 time = 0;
const int repeat = 11;
// Repeat the operation several times to amplify the time difference.
for (int i = 0; i < repeat; ++i)
{
time += time_call([&] {
parallel_for(0, size/2, [&](int index)
{
swap(a, index, size-index-1);
});
});
}
delete[] a;
return time;
}
int wmain()
{
// Compute the time that it takes to reverse large arrays of
// different types.
// new_delete
wcout << L"Took " << reverse_array<new_delete>()
<< " ms with new/delete." << endl;
// malloc_free
wcout << L"Took " << reverse_array<malloc_free>()
<< " ms with malloc/free." << endl;
// Alloc_Free
wcout << L"Took " << reverse_array<Alloc_Free>()
<< " ms with Alloc/Free." << endl;
}
In questo esempio viene generato l'output di esempio seguente per un computer con quattro processori.
Took 2031 ms with new/delete.
Took 1672 ms with malloc/free.
Took 656 ms with Alloc/Free.
In questo esempio, il tipo che usa le Alloc funzioni e Free offre le migliori prestazioni di memoria perché le Alloc funzioni e Free sono ottimizzate per l'allocazione e la liberazione frequente di blocchi di memoria da più thread.
Compilazione del codice
Copiare il codice di esempio e incollarlo in un progetto di Visual Studio oppure incollarlo in un file denominato allocators.cpp e quindi eseguire il comando seguente in una finestra del prompt dei comandi di Visual Studio.
cl.exe /EHsc allocators.cpp
Vedi anche
Funzioni di gestione della memoria
Funzione Alloc
Funzione libera