opengl: glFlush () по сравнению с glFinish ()

Я испытываю затруднения при различении практического различия между вызовом glFlush() и glFinish().

В документах говорится это glFlush() и glFinish() продвинет все буферизированные операции к OpenGL так, чтобы можно было быть уверен, что они будут все выполняться, при этом различие будет этим glFlush() возвраты сразу, где как glFinish() блоки до всех операций завершены.

Прочитав определения, я полагал это, если я должен был использовать glFlush() то, что я, вероятно, столкнулся бы с проблемой представления большего количества операций к OpenGL, чем это могло выполниться. Так, только для попытки я выгрузил мой glFinish() для a glFlush() и о чудо, моя программа работала (насколько я мог сказать), то же самое; частота кадров, использование ресурсов, все было тем же.

Таким образом, я задаюсь вопросом, существует ли много различия между двумя вызовами, или если мой код заставляет их работать не отличающийся. Или где нужно использоваться по сравнению с другим. Я также полагал, что OpenGL будет иметь некоторый вызов как glIsDone() проверять действительно ли все буферизированные команды на a glFlush() завершены или не (таким образом, каждый не отправляет операции в OpenGL быстрее, чем они могут быть выполнены), но я не мог найти такую функцию.

Мой код является типичным игровым циклом:

while (running) {
    process_stuff();
    render_stuff();
}
101
задан plasmacel 14 March 2019 в 22:34
поделиться

6 ответов

Имейте в виду, что эти команды существуют с первых дней существования OpenGL. glFlush гарантирует, что предыдущие команды OpenGL должны быть завершены в конечное время (OpenGL 2.1 specs, page 245). Если же жеребьевка проводится непосредственно в переднем буфере, то это должно обеспечить, чтобы водители OpenGL начали жеребьевку без слишком большой задержки. Можно придумать сложную сцену, которая появляется на экране по очереди за объектом, когда вы вызываете glFlush после каждого объекта. Однако, при использовании двойной буферизации, glFlush практически не оказывает никакого эффекта, так как изменения не будут видны до тех пор, пока Вы не поменяете буферы.

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

Так что, если вы используете двойную буферизацию, вам, вероятно, не понадобится ни glFlush, ни glFinish. SwapBuffers неявно направляет вызовы OpenGL в правильный буфер, нет необходимости сначала вызывать glFlush . И не обращайте внимания на драйвер OpenGL: glFlush не подавится слишком большим количеством команд. Не гарантируется, что этот вызов вернётся немедленно (что бы это ни значило), так что может занять любое время, необходимое для обработки ваших команд.

91
ответ дан 24 November 2019 в 04:44
поделиться

Если вы не видели никаких разниц производительности, это означает, что вы делаете что-то не так. Как упомянуты некоторые другие, вам не нужно либо звонить, но если вы звоните Glfinish, вы автоматически теряете параллелизм, что GPU и CPU могут достичь. Позвольте мне погружаться глубже:

На практике все работа, которую вы подчиняете водителю, получают дозацию, и отправляются на оборудование потенциально позже (например, в Swapbuffer Time).

Итак, если вы звоните в Glfinish, вы по сути, вы принудите водителя толкать команды GPU (что он добился до этого, и никогда не спрашивал GPU на работу), и остановить CPU до команд. толкают полностью выполнены. Таким образом, в течение всего времени работы GPU процессор не (по крайней мере, на этой теме). И все время процессор делает свою работу (в основном дозирующиеся команды), GPU ничего не делает. Итак, да, глифин должен повредить вашу работу. (Это приближение, так как драйверы могут начать работу GPU на некоторых командах, если многие из них уже были насыщены. Это не типично, хотя буферы команд, как правило, имеют достаточно большие, чтобы удержаться довольно много команд).

Теперь, почему вы вообще звонили в Glfinish? Единственные раз, когда я использовал это, когда у меня были ошибки водителя. Действительно, если один из команд, которые вы отправляете в аппаратное обеспечение, сбивают GPU, то ваша простая опция определить, какую команду является виновником, состоит в том, чтобы вызовать Glfinish после каждого розыгрыша. Таким образом, вы можете сузить то, что именно триггеры авария

как боковая заметка, API, как Direct3D, не поддерживает концепцию окончания.

6
ответ дан 24 November 2019 в 04:44
поделиться

Вопрос: Хотите ли вы, чтобы ваш код продолжить работу, когда команды OpenGL выполняются, или только для запуска после выполнены ваши команды OpenGL.

Это может иметь значение в случаях, как над сетевыми задержками, иметь только определенный выход консоли после . Изображения были нарисованы или такое.

0
ответ дан 24 November 2019 в 04:44
поделиться

Как намекнули другие ответы, на самом деле нет хорошего ответа согласно спецификации. Общий смысл glFlush() заключается в том, что после его вызова центральному процессору хоста не нужно будет выполнять никаких работ, связанных с OpenGL - команды будут подталкиваться к графическому оборудованию. Общее назначение glFinish() заключается в том, что после его возврата, нет оставшейся работы, и результаты должны быть доступны также и всем соответствующим не-ОpenGL API (например, чтение из фрейм-буфера, скриншотов и т.д....). Действительно ли это происходит, зависит от драйверов. Спецификация допускает тонну широты в отношении того, что является легальным.

21
ответ дан 24 November 2019 в 04:44
поделиться

Необходимо встроить UITableView в UIView вместе с другим представлением (которое называется заголовочным разделом).

Таким образом, UIView будет иметь 2 подраздела. Ракурс заголовка, за которым следует ракурс таблицы.

  • UIView (родительский)
    • UIView (заголовок)
    • UITableView (таблица)

Надеюсь, это поможет.

-121--1217111-

Это плохой стиль (хотя и легальный). Это будет работать, но это означает, что компилятор не может проверить ваши аргументы. Так что если вы случайно называете свою функцию так:

s.Push(arg, &s);   // oops, reverse the arguments

компилятор не сможет сказать вам, что вызов плохой.

До стандартизации ANSI у K & R C не было прототипов; он поддерживает только объявления, в которых указан возвращаемый тип. При исключении аргументов используется эта архаичная функция.

Для включения предупреждений при их использовании в gcc можно использовать опцию -Wstrict-prototypes .

-121--4859623-

Не существует способа запроса состояния буфера. Существует расширение Apple , которое может служить той же цели, но оно не кажется кроссплатформенным (не пробовал). На этот быстрый взгляд, кажется, что до смыть вы бы нажали команду ограды; Затем можно запросить состояние этого ограждения при его перемещении через буфер.

Интересно, можно ли использовать flush перед буферизацией команд, но перед началом визуализации следующего кадра вызвать finish . Это позволит начать обработку следующего кадра по мере работы графического процессора, но если это не будет сделано к тому времени, когда вы вернетесь, finish заблокирует, чтобы убедиться, что все в свежем состоянии.

Я не пробовал это, но скоро.

Я попробовал его на старом приложении, которое почти даже использует процессор и графический процессор. (Первоначально использовалась finish .)

Когда я изменил ее на flush в конце и finish в начале, проблем не возникло. (Все выглядело хорошо!) Быстродействие программы увеличилось, вероятно, из-за того, что процессор не остановился в ожидании графического процессора. Определенно лучший метод.

Для сравнения я убрал готовый из начала кадра, оставив смытым , и он выполнил то же самое.

Поэтому я бы сказал, используйте flush и finish , потому что, когда буфер пуст при вызове finish , не достигается производительность. И я предполагаю, если буфер был заполнен, вы должны хотеть закончить в любом случае.

3
ответ дан 24 November 2019 в 04:44
поделиться

PowerPoint имеет доступ к VBA правильно? ( Да, я проверил ) Таким образом, вы сможете автоматизировать генерацию путь. Я сделал это довольно много, но в документе Excel. Я никогда не пробовал это с точки зрения силы.

Проблема теперь становится одной из временных инвестиций? Узнайте, как сделать это с помощью VBA или сделать это вручную... Если это может быть обычным делом, я бы посоветовал вам научиться делать это через VBA. Вообще говоря, я обнаружил, что автоматизация Excel с VBA не была слишком сложной, когда вы поняли основы. Сэкономленное время определенно стоило того в долгосрочной перспективе.

Наконец, я хотел бы порекомендовать книгу, чтобы начать, но, увы, я никогда не думал попробовать это, поэтому я никогда не вкладывал в исследование этого.

-121--3702209-

Из MSDN вы обнаружите, что DateTime.Now имеет приблизительное разрешение 10 миллисекунд во всех операционных системах NT.

Фактическая точность зависит от аппаратных средств. Более высокую точность можно получить с помощью QuurePerformureCounter .

-121--771967-

Посмотрите здесь . Короче говоря, он говорит:

glFinish () имеет тот же эффект, что и glFlush (), с добавлением того, что glFinish () будет блокировать до тех пор, пока не будут выполнены все переданные команды.

Другая статья описывает другие различия:

  • Функции замены (используются в приложениях с двойным буфером) автоматически сбрасывать команды, поэтому нет необходимости вызывать glFlush
  • glFinish заставляет OpenGL выполнять выдающиеся команды, что является плохой идеей (например, с VSync)

Для подведения итогов это означает, что эти функции даже не нужны при использовании двойной буферизации, за исключением случаев, когда реализация swap-буферов не выполняет автоматическую очистку команд.

4
ответ дан 24 November 2019 в 04:44
поделиться