Устройству потребовалось неоправданно много времени для выполнения своих команд.

Я портирую код C на HLSL (вычислительный шейдер). Компилятор без ума от одного из циклов for. Во время выполнения драйвер устройства отображения обнаруживает неоправданное количество времени для выполнения кода.

Вот частичный исходный код с оскорбительным циклом for:

P = FloatToAsciiNoExponent(F * Factor, DstBuf, 7);
uint TmpBuf[FTOA_BUFFER_SIZE];
uint BytesWritten = IntToAscii(Exp10, TmpBuf, BASE10);
DstBuf[P++] = 'E';
[fastopt]
for (uint I = 0; I < BytesWritten; I++)
    DstBuf[P++] = TmpBuf[I];

Во время выполнения я получил следующее сообщение отладки:

D3D11 ОШИБКА: ID3D11Device :: RemoveDevice: удаление устройства было инициировано по следующей причине (DXGI_ERROR_DEVICE_HUNG: устройству потребовалось неоправданно много времени для выполнения своих команд, либо аппаратное обеспечение вышло из строя / зависло. В результате TDR (Timeout Detection and Recovery) был запущен. Текущий контекст устройства выполнял команды, когда произошло зависание. Приложение может захотеть возродиться и вернуться к менее агрессивному использованию оборудования дисплея). ОШИБКА ВЫПОЛНЕНИЯ № 378: DEVICE_REMOVAL_PROCESS_AT_FAULT]

Если я закомментирую две строки цикла for, все в порядке (кроме, конечно, окончательного результата, в котором отсутствует его последняя часть).

FloatToAsciiNoExponent() - это функция, которая преобразует его первый аргумент в список или код ascii, хранящийся во втором аргументе (массив uint). Последний аргумент - это база счисления для преобразования. Это было подтверждено.

IntToAscii() - это функция, преобразующая его первый аргумент в список кода ascii, хранящийся во втором аргументе (массив uint). Это было подтверждено.

Исходный исходный код C, который я портирую, можно найти здесь: https://searchcode.com/codesearch/view/14753060/

Я использую Windows 7 и DirectX SDK от июня 2010 года (последний работает в Windows 7). Обновление Windows выполнено, и все обновления установлены. Графическая карта представляет собой NVidia Quadro K4200 с 24 ГБ оперативной памяти с версией драйвера 431.02.

Любая помощь приветствуется.


person fpiette    schedule 27.08.2019    source источник


Ответы (2)


При использовании DirectCompute вам все равно нужно убедиться, что каждый экземпляр завершается в разумные сроки, иначе вы достигнете таймаутов TDR (~ 2 секунды).

См. Документы Microsoft.

С DirectX 11.1 (Windows 8 или новее) вы можете использовать D3D11_CREATE_DEVICE_DISABLE_GPU_TIMEOUT, чтобы дать вам немного больше времени для долго работающего шейдера DirectCompute, но вы можете сделать систему не отвечающей.

Вы можете установить частичную версию DirectX 11.1 в Windows 7 с пакетом обновления 1 с помощью KB2670838

Вам также следует прочитать этот пост в блоге для получения более свежей информации о устаревшем DirectX SDK.

ОБНОВЛЕНИЕ По-видимому, на самом деле это была ошибка компилятора HLSL в устаревшем DirectX SDK. Обратите внимание, что вы можете и должны использовать последнюю версию компилятора HLSL для Windows 10 SDK даже для DirectX 11 в Windows 7. См. это сообщение в блоге и Microsoft Docs.

person Chuck Walbourn    schedule 27.08.2019
comment
Спасибо. Да, я знаю. Проблема не в этом. Код в цикле выполняется не более 16 раз и представляет собой всего лишь копию uint из одного массива в другой. Ничего, что требует много времени. Я предполагаю, что каким-то образом компилятор генерирует неправильный код. KB2670838 уже установлен в моей системе, которая, как я уже сказал, полностью обновлена ​​для WIN7. - person fpiette; 28.08.2019
comment
Я обновил свой компьютер до Win10, который включает DirectX12. Теперь исходный код работает как положено. Это подтверждает, что компилятор июня 2010 года содержит ошибки. - person fpiette; 30.08.2019

Отвечая себе:

Я обновил свой компьютер до Win10, который включает DirectX12. Теперь исходный код работает как положено. Это подтверждает, что компилятор июня 2010 года содержит ошибки.

person fpiette    schedule 05.09.2019