방법: Alloc 및 Free를 사용하여 메모리 성능 개선How to: Use Alloc and Free to Improve Memory Performance

이 문서에서는 concurrency:: AllocConcurrency:: Free 함수를 사용 하 여 메모리 성능을 향상 시키는 방법을 보여 줍니다.This document shows how to use the concurrency::Alloc and concurrency::Free functions to improve memory performance. 각각 newdelete 연산자를 지정 하는 세 가지 서로 다른 형식에 대해 배열의 요소를 병렬 처리 하는 데 필요한 시간을 비교 합니다.It compares the time that is required to reverse the elements of an array in parallel for three different types that each specify the new and delete operators.

AllocFree 함수는 여러 스레드가 AllocFree를 모두 자주 호출 하는 경우에 가장 유용 합니다.The Alloc and Free functions are most useful when multiple threads frequently call both Alloc and Free. 런타임은 각 스레드를 위해 별도의 메모리 캐시를 보유하므로 런타임에서는 잠금 또는 메모리 차단을 사용하지 않아도 메모리를 관리할 수 있습니다.The runtime holds a separate memory cache for each thread; therefore, the runtime manages memory without the use of locks or memory barriers.

예제Example

다음 예제에서는 각각 newdelete 연산자를 지정 하는 세 가지 형식을 보여 줍니다.The following example shows three types that each specify the new and delete operators. new_delete 클래스는 global newdelete 연산자를 사용 하 고 malloc_free 클래스는 C 런타임 mallocfree 함수를 사용 하며 Alloc_Free 클래스는 동시성 런타임 AllocFree 함수를 사용 합니다.The new_delete class uses the global new and delete operators, the malloc_free class uses the C Runtime malloc and free functions, and the Alloc_Free class uses the Concurrency Runtime Alloc and Free functions.

// 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;
};

예제Example

다음 예제에서는 swapreverse_array 함수를 보여 줍니다.The following example shows the swap and reverse_array functions. swap 함수는 지정 된 인덱스에 있는 배열의 내용을 교환 합니다.The swap function exchanges the contents of the array at the specified indices. 이 함수는 임시 변수를 위해 힙에서 메모리를 할당합니다.It allocates memory from the heap for the temporary variable. reverse_array 함수는 많은 배열을 만들고 해당 배열을 병렬로 여러 번 되돌리는 데 필요한 시간을 계산 합니다.The reverse_array function creates a large array and computes the time that is required to reverse that array several times in parallel.

// 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;
}

예제Example

다음 예제에서는 reverse_array 함수가 서로 다른 메모리 할당 체계를 사용 하는 new_delete, malloc_freeAlloc_Free 형식에서 작동 하는 데 필요한 시간을 계산 하는 wmain 함수를 보여 줍니다.The following example shows the wmain function, which computes the time that is required for the reverse_array function to act on the new_delete, malloc_free, and Alloc_Free types, each of which uses a different memory allocation scheme.

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;
}

예제Example

다음은 완성된 예제입니다.The complete example follows.

// 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;
}

프로세서가 4개인 컴퓨터에서 이 예제를 실행하면 다음과 같은 샘플 결과가 출력됩니다.This example produces the following sample output for a computer that has four processors.

Took 2031 ms with new/delete.
Took 1672 ms with malloc/free.
Took 656 ms with Alloc/Free.

이 예제에서 AllocFree 함수를 사용 하는 형식은 여러 스레드의 메모리 블록을 자주 할당 하 고 해제 하기 위해 AllocFree 함수를 최적화 하기 때문에 최상의 메모리 성능을 제공 합니다.In this example, the type that uses the Alloc and Free functions provides the best memory performance because the Alloc and Free functions are optimized for frequently allocating and freeing blocks of memory from multiple threads.

코드 컴파일Compiling the Code

예제 코드를 복사 하 여 Visual Studio 프로젝트에 붙여넣거나, allocators.cpp 이름이 지정 된 파일에 붙여 넣은 후 Visual Studio 명령 프롬프트 창에서 다음 명령을 실행 합니다.Copy the example code and paste it in a Visual Studio project, or paste it in a file that is named allocators.cpp and then run the following command in a Visual Studio Command Prompt window.

cl.exe/EHsc 할당자 .cppcl.exe /EHsc allocators.cpp

참고 항목See also

메모리 관리 함수Memory Management Functions
Alloc 함수Alloc Function
Free 함수Free Function