Из любопытства и некоторых странных наблюдений за поведением.
Как выглядит адресное пространство для процесса x86 при распределении как самого процесса с использованием функций управления памятью win32 (malloc/new afterall
), так и выделения текстур на интегрированном Intel GPU, который использует общую память компьютера? Являются ли распределения GPU частью адресного пространства процесса? С тех пор, как я видел сегодня, что-то странное, что происходит с моим процессом. Я использую x86-процесс на машине x64, мой объем памяти, обработанный процессом, составляет ~ 1.3 ГБ, потребление памяти общей памяти GPU составляет ~ 600 МБ, и я начинаю получать ENOMEM
от HeapAlloc
при попытке выделить 32-мегабайтный буфер. Я не считаю, что фрагментация - это то, с чем нужно иметь дело, поскольку процесс проходит до минуты. Поэтому у меня сложилось впечатление, что память GPU подсчитывается в адресном пространстве процесса, иначе я не могу объяснить, почему HeapAlloc
возвращает null для кучи CRT. Сторона примечания, связанная DLL без/LARGEADDRESSAWARE, поэтому 2Gb выглядит как сумма вышеуказанных чисел (1.3 + 0.6)
Я прав? Неправильно? Может ли кто-нибудь объяснить, как это работает?Память процесса, общая память GPU и процесс x86 на адресном пространстве x64 окон
EDIT001: небольшое разъяснение, графический процессор потребляет ~ 600 ГБ не из-за синего, но поскольку я выделяю текстуры с помощью DirectX.
EDIT002: тест добавлен Я пропустил инициализацию устройства здесь
constexpr size_t dim = 5000; CD3D11_TEXTURE2D_DESC texDescriptor (DXGI_FORMAT_D24_UNORM_S8_UINT, dim, dim, 1, 1, D3D11_BIND_DEPTH_STENCIL);
std::vector<std::vector<uint8_t>> procData;
std::vector<CComPtr<ID3D11Texture2D>> gpuData;
// Some device/context init here
for(;;)
{
{
CComPtr<ID3D11Texture2D> tex;
hr = device->CreateTexture2D(&texDescriptor, nullptr, &tex);
if(SUCCEEDED(hr))
{
gpuData.emplace_back(tex);
}
else
{
std::cout << "Failed to create " << gpuData.size() << "th texture." << std::endl;
}
}
{
try
{
std::vector<uint8_t> buff(dim * dim, 0);
procData.emplace_back(buff);
}
catch(std::exception& ex)
{
std::cout << "Failed to create " << procData.size() << "th buffer." << std::endl;
}
}
}
Напомним, что x86 процесс, без установки LARGEADRESSAWARE, поэтому, 2Gb в его распоряжении. Приведенный выше код создает 35 буферов и 34 текстур. Если вы закомментируете блок создания текстуры, создаются 70 буферов. Хорошо ...
Я не эксперт в области графического процессора, но сопоставление виртуальной памяти для любого указанного процесса можно легко визуализировать с помощью [VMMap] (https://technet.microsoft.com/en-us/sysinternals/vmmap.aspx). Я предлагаю вам играть с этим инструментом и печатать адреса буферов, которые вам интересны, поэтому вы можете определить, к какому разделу они принадлежат. –
Уже сделал это ... нет ничего особенного вначале, посмотрите цифру – kreuzerkrieg