Есть ли в OpenCL и OpenGL SL "неопределенное поведение"? - PullRequest
2 голосов
/ 17 сентября 2011

Мне сказали, что C и C ++ имеют "неопределенное поведение", то есть один и тот же код может вести себя по-разному на разных платформах или с использованием разных компиляторов, если я использую "определенные конструкции".

То же самое относится к OpenCL и / или OpenGL SL?

Ответы [ 4 ]

4 голосов
/ 17 сентября 2011
3 голосов
/ 17 сентября 2011

Да, в соответствии со спецификацией OpenCL 1.1 , которая определяет неопределенное поведение в начале как:

Поведение вызова API OpenCL, встроенная функция, используемая внутриядро или выполнение ядра, которое явно не определено OpenCL.Соответствующая реализация не требуется для указания того, что происходит, когда в OpenCL

встречается неопределенная конструкция. Например:

  • В разделе 5.2.1 определены несколько:
    • "Чтение из буфера или объекта изображения, созданного с помощью CL_MEM_WRITE_ONLY внутри ядра"
    • "Запись в буфер или объект изображения, созданного с помощью CL_MEM_READ_ONLY внутри ядра"
    • "OpenCLкоманды, которые работают с несколькими объектами буфера, созданными с одним и тем же host_ptr или перекрывающимися областями хоста "
    • " Параллельное чтение, запись и копирование между перекрывающимися объектами подпуфера, созданными с одним и тем же объектом буфера "
  • Раздел 5.2.2 также определяет несколько:
    • clEnqueueReadBuffer с другими командами, использующими буфер
    • clEnqueueReadBuffer, в то время как буфер отображается

Существует еще много способов вызова неопределенного поведения из OpenCL.

Для OpenGL SL ( спецификация ) существует довольно много простых способов.o найти примеры:

  • "Неопределенное поведение возникает в результате индексации массива с непостоянным выражением, которое больше или равно размеру массива или меньше 0" (Интересно, если это const, тоэто ошибка времени компиляции)
  • Аналогично для доступа к векторным элементам с помощью индексации массива
  • «Чтение переменной переменной в вершинном шейдере возвращает неопределенные значения, если она читается до записи» *
  • "Если эта прагма [#pragma STDGL invariant(all)] используется после объявления каких-либо переменных или функций, то набор выходов, которые ведут себя как инвариант, не определен"
  • "Чтение [gl_PointSize или gl_ClipVertex] перед записью их приводит к неопределенному поведению "
  • и т. д.
2 голосов
/ 17 сентября 2011

Мне сказали, что C и C ++ имеют "неопределенное поведение", то есть один и тот же код может вести себя по-разному на разных платформах или с использованием разных компиляторов, если я использую "определенные конструкции".

Это не то, что на самом деле означает неопределенное поведение.Это результат неопределенного поведения, но это не то, для чего он нужен.

Спецификации предназначены для определения того, что происходит, когда вы что-то делаете.Он говорит, какие значения параметров хороши, а какие плохи.Если вы пропустите плохие, он скажет вам, какие ошибки вы получаете и каково будет состояние системы.Если текущее состояние недопустимо для операции, которую вы пытаетесь выполнить, спецификация объясняет, какие другие виды ошибок вы получаете и что это означает для состояния системы впоследствии.

Когда вы используете определенное поведение, выполагаться на договор между вами и реализацией;этот контракт называется спецификацией OpenGL.Вы полагаетесь на реализацию, чтобы обеспечить проверки достоверности, требуемые спецификацией.И вы полагаетесь на реализацию, делающую то, что сказано в спецификации.Если реализация не реализует что-то правильно, то это нарушает контракт.

Когда спецификация говорит, что определенный набор вещей приведет к "неопределенному поведению", это означает, что выполнение этих вещей является Вы нарушаете контракт.Вы находитесь за краем карты.Вы делаете что-то, для чего спецификация не обеспечивает определенного поведения;Вы нарушили свою часть соглашения.

Другими словами, ваш код будет идеально переносимым , пока вы не полагаетесь на неопределенное поведение.Вот что это значит.

Как правило, спецификация помечает что-то неопределенное, если ее тестирование является обременительным бременем для реализаций.В конце концов, OpenGL должен быть достаточно быстрым.Так что обременять водителя, заставляя его проверять вещи, которые почти невозможно проверить, - это то, чего они пытаются избежать.

Затем, существуют тесты, которые невозможно протестировать.В OpenGL запрещено считывать и записывать одно и то же изображение, связывая изображение как текстуру и сэмплируя его, одновременно прикрепляя это изображение к FBO и обрабатывая его.Невозможно гарантированно протестировать этот сценарий.

О, вы можете протестировать большинство из них.Вы можете потерпеть неудачу при вызовах отрисовки, когда одна и та же текстура связана с FBO и сэмплером.Но тогда вы не сможете рендерить разные мипмапы одной и той же текстуры;помните: каждый mipmap - это отдельное изображение.Таким образом, вы можете проверить, позволяет ли диапазон базового / максимального уровня предусмотреть возможность выборки из mipmap, привязанного к FBO.Но это ложится тяжелым бременем на пользователя, так как ему придется постоянно корректировать базовый / максимальный уровень при рендеринге на разные мипмапы.Им гораздо проще просто выбрать правильный mipmap с textureLOD или подобными функциями.И вы не сможете до времени выполнения определить, производят ли они выборку извне этого уровня mipmap.

OpenCL и OpenGL SL имеют неопределенное поведение, как и многие спецификации.И, как правило, он не определен по тем же причинам: его тестирование может сделать реализацию неприемлемо медленной, или тестирование невозможно.

1 голос
/ 17 сентября 2011

Да, есть неопределенное поведение (вы можете найти спецификацию, чтобы найти некоторые);но будьте осторожны, потому что это не единственный способ для программы вести себя по-разному в разных системах: не все реализации OpenGL полностью совместимы (фактически, скорее всего, большинство из них не так).Например, драйверы Nvidia позволяют вызывать texture2D в профиле ядра здесь, в то время как это вызывает ошибку на других платформах (и это ожидаемое поведение).Лучший способ узнать, сработает ли он, - это протестировать на нескольких платформах (ОС, графические процессоры и драйверы).

...