У меня есть задача проверить, может ли разработанный мной алгоритм работать быстрее, используя вычисления на GPU, а не на CPU. Я новичок в вычислениях на ускорителях, мне дали книгу «C ++ AMP», которую я полностью прочитал, и я подумал, что достаточно хорошо ее понял (я программировал на C и C ++ в прошлом, но сейчас это в основном C #).
Однако при входе в реальное приложение я, похоже, просто не понимаю. Пожалуйста, помогите мне, если сможете.
Допустим, у меня есть задача вычислить некоторую сложную функцию, которая требует огромного матричного ввода (например, 50000 x 50000) и некоторых других данных и матрицы вывода того же размера. Общий расчет всей матрицы занимает несколько часов.
Что касается процессора, я бы просто разрезал задачи на несколько частей (количество штук было около 100 или около того) и выполнял их, используя Parralel.For или простой цикл управления задачами, который я написал сам. По сути, поддерживайте работу нескольких потоков (количество потоков = количество ядер), начинайте новую часть после завершения потока, пока все части не будут выполнены. И это сработало хорошо!
Однако на GPU я не могу использовать тот же подход не только из-за ограничений памяти (это нормально, может разделиться на несколько частей), но и из-за того факта, что если что-то выполняется более 2 секунд, это считается «тайм-аутом» и GPU получает сброс! Итак, я должен убедиться, что каждая часть моего вычисления занимает менее 2 секунд.
Но это не каждая задача (например, разделить часовую работу на 60 задач по 1 секунде каждая), что было бы достаточно просто, вот и все задачи, потому что независимо от того, какой режим очереди я выберу (немедленный или автоматический), если я Запустите (через parralel_for_each) все, что в общей сложности занимает более 2 секунд, GPU будет сброшен.
И не только это, но если моя программа ЦП захватывает все ресурсы ЦП, пока он поддерживается в более низком приоритете, пользовательский интерфейс остается интерактивным — система реагирует, однако при выполнении кода на графическом процессоре кажется, что экран зависает до завершения выполнения !
Итак, что мне делать? В демонстрациях к книге (проблема N-Body) она показывает, что она должна быть примерно в 100 раз более эффективной (многоядерные вычисления дают 2 флопс, или w / e количество флопов, которое было, в то время как ампер дает 200 гфлопс), но в реальном приложении я просто не вижу, как это сделать!
Нужно ли разбивать мою большую задачу на подобные, на миллиарды частей, например, на части, каждая из которых занимает 10 мс для выполнения и запускает 100 из них в parralel_for_each за раз?
Или я просто делаю это неправильно, и есть лучшее решение, которое я просто не понимаю?
Помогите, пожалуйста!
TDR (тайм-ауты 2 с, которые вы видите) — это реальность использования ресурса, который используется для рендеринга дисплея и выполнения ваших вычислительных работ. ОС защищает ваше приложение от полной блокировки дисплея, применяя тайм-аут. Это также повлияет на приложения, которые пытаются отобразить на экране. Перемещение кода AMP в отдельный поток ЦП не поможет, это освободит ваш поток пользовательского интерфейса на ЦП, но рендеринг все равно будет заблокирован на GPU.
На самом деле вы можете увидеть это поведение в примере с n-body, когда вы устанавливаете N очень большим в системе с низким энергопотреблением. Максимальное значение N на самом деле ограничено в приложении, чтобы вы не столкнулись с этими типами проблем в типичных сценариях.
Вы на самом деле на правильном пути. Вам действительно нужно разбить свою работу на куски, которые вписываются в чанки с частотой 2 с или меньшие, если вы хотите достичь определенной частоты кадров. Вы должны также рассмотреть, как ваша работа ставится в очередь. Помните, что вся работа AMP ставится в очередь, и в автоматическом режиме вы не можете контролировать ее запуск. Использование немедленного режима — это способ лучше контролировать процесс пакетирования команд.
Примечание: TDR не являются проблемой на выделенном оборудовании для вычислительных графических процессоров (например, Tesla), и Windows 8 предлагает большую гибкость при работе с ограничениями времени ожидания TDR, если базовый графический процессор поддерживает его.
Других решений пока нет …