Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Dit document laat zien hoe u de gelijktijdigheid:::Alloc en gelijktijdigheid:::Gratis functies gebruikt om de geheugenprestaties te verbeteren. Het vergelijkt de tijd die nodig is om de elementen van een matrix parallel om te draaien voor drie verschillende typen die elk de new en delete operators opgeven.
De Alloc en Free functies zijn het handigst wanneer meerdere threads vaak zowel Alloc als Free aanroepen. De runtime bevat een afzonderlijke geheugencache voor elke thread; Daarom beheert de runtime het geheugen zonder het gebruik van vergrendelingen of geheugenbarrières.
Voorbeeld: Typen die nieuwe operators opgeven en verwijderen
In het volgende voorbeeld ziet u drie typen die elk de new en delete operators opgeven. De new_delete klasse maakt gebruik van de globale new operatoren, de delete klasse maakt gebruik van de C Runtime functies malloc_free en free, en de klasse maakt gebruik van de Gelijktijdigheidsruntime Alloc_Free en Alloc functies.
// 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;
};
Voorbeeld: swap en omgekeerde_array functies
In het volgende voorbeeld ziet u de swap functies en reverse_array functies. De swap functie wisselt de inhoud van de matrix uit bij de opgegeven indexen. Geheugen wordt toegewezen vanuit de heap voor de tijdelijke variabele. De reverse_array functie maakt een grote matrix en berekent de tijd die nodig is om die matrix meerdere keren parallel om te draaien.
// 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;
}
Voorbeeld: wmain-functie
In het volgende voorbeeld ziet u de wmain functie, waarmee de tijd wordt berekend die nodig is om de functie te laten reageren op de reverse_arraynew_delete, malloc_freeen Alloc_Free typen, die elk een ander schema voor geheugentoewijzing gebruiken.
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;
}
Voorbeeld van volledige code
Het volledige voorbeeld volgt.
// 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 dit voorbeeld wordt de volgende voorbeelduitvoer geproduceerd voor een computer met vier processors.
Took 2031 ms with new/delete.
Took 1672 ms with malloc/free.
Took 656 ms with Alloc/Free.
In dit voorbeeld biedt het type dat gebruikmaakt van de Alloc en Free functies de beste geheugenprestaties, omdat de Alloc en Free functies zijn geoptimaliseerd voor het regelmatig toewijzen en vrijmaken van blokken geheugen uit meerdere threads.
De code compileren
Kopieer de voorbeeldcode en plak deze in een Visual Studio-project, of plak deze in een bestand met de naam allocators.cpp en voer vervolgens de volgende opdracht uit in een Visual Studio-opdrachtpromptvenster.
cl.exe /EHsc-allocators.cpp