Performance regression when rendering at very high resolution #82591

Closed
opened 2020-11-10 18:21:48 +01:00 by Richard Antalik · 25 comments

System Information
Operating system: Windows-10-10.0.19041-SP0 64 Bits
Graphics card: Radeon RX550/550 Series ATI Technologies Inc. 4.5.14736 Core Profile Context 20.8.3 27.20.12027.1001

Blender Version
Broken: version: 2.92.0 Alpha, branch: master, commit date: 2020-11-09 14:47, hash: 4f66cf3b8b
Worked: blender-2.90.1-windows64

Short description of error
Time to render:
2.90.1: ~4min
2.92: ~30min

Exact steps for others to reproduce the error
#82591.blend

  • Open file
  • Set User Preferences > Interface > Render In to Keep User Interface
  • Render image (CPU)
**System Information** Operating system: Windows-10-10.0.19041-SP0 64 Bits Graphics card: Radeon RX550/550 Series ATI Technologies Inc. 4.5.14736 Core Profile Context 20.8.3 27.20.12027.1001 **Blender Version** Broken: version: 2.92.0 Alpha, branch: master, commit date: 2020-11-09 14:47, hash: `4f66cf3b8b` Worked: blender-2.90.1-windows64 **Short description of error** Time to render: 2.90.1: ~4min 2.92: ~30min **Exact steps for others to reproduce the error** [#82591.blend](https://archive.blender.org/developer/F9253849/T82591.blend) - Open file - Set User Preferences > Interface > Render In to Keep User Interface - Render image (CPU)
Author
Member

Added subscriber: @iss

Added subscriber: @iss

#85308 was marked as duplicate of this issue

#85308 was marked as duplicate of this issue

#83011 was marked as duplicate of this issue

#83011 was marked as duplicate of this issue
Brecht Van Lommel changed title from Performance regression when rendering large files to Performance regression when rendering at very high resolution 2020-11-10 18:25:30 +01:00
Member

Added subscriber: @Alaska

Added subscriber: @Alaska
Member

I'm personally able to reproduce this issue on Linux with a Ryzen 9 3900X. Testing with old versions of Blender I have on my computer, I can reproduce it even back with Blender version 2.91.0 1b04eb6c44 (2020-10-10 16:05).

I'm currently running a bisect to find the culprit commit. I'll comment back when I'm finished.

I'm personally able to reproduce this issue on Linux with a Ryzen 9 3900X. Testing with old versions of Blender I have on my computer, I can reproduce it even back with Blender version 2.91.0 `1b04eb6c44` (2020-10-10 16:05). I'm currently running a bisect to find the culprit commit. I'll comment back when I'm finished.
Member

Added subscriber: @Jeroen-Bakker

Added subscriber: @Jeroen-Bakker
Member

Bisecting points to 4212b6528a

CC @Jeroen-Bakker

Bisecting points to 4212b6528a CC @Jeroen-Bakker
Member

Changed status from 'Needs Triage' to: 'Confirmed'

Changed status from 'Needs Triage' to: 'Confirmed'
Member

When cycles is rendering it creates a render result for specific tiles (offset + dimension) to the actual render result. It calls the rect on the RenderPass. This will sync a tile to blender. and call the RE_engine_end_result; what will sync the tile result back to the full image (`render_result_merge).

The render API has an option to only update a section of the display based on a given rect. The display update is set to image_rect_update when rendering. This function taggs the image with a IMA_GPU_REFRESH and marks the GPUTexture of the image as obsolete.

The next time the GPUTexture is used/requested a new GPUTexture is created. During this creation process the image is scaled to match the size of the GPUTexture. If the image does not fit on the GPU it is scaled down.

We could add partial updates of GPUTextures so only the new data needs to be scaled (IMA_GPU_PARTIAL_REFRESH). the rects that needs to be refreshed could be hold in a list on the ImBuf.

NOTE: IMA_GPU_PARTIAL_REFRESH can be promoted to IMA_GPU_REFRESH.

There is already a function that can update a part of a GPU texture IMB_update_gpu_texture_sub. But there is room for improvement here. as it uses imb_gpu_get_data that still converts and scales the full image.

Proposed solution

  • Modify IMB_update_gpu_texture_sub to be able to update a part of the source image. Currently it copies the full source image to a defined part on the GPUTexture.
    ** Create imb_gpu_get_sub_data that is similar to imb_gpu_get_data but doesn't convert/scale the full image. Use this function in.
  • Add IMA_GPU_PARTIAL_REFRESH
    ** change image_rect_update to use IMA_GPU_PARTIAL_REFRESH
  • Keep track of parts of the image that needs to be refreshes. I would start with a linked list as that is more scalable when rendering on 64 cores.
When cycles is rendering it creates a render result for specific tiles (offset + dimension) to the actual render result. It calls the `rect` on the RenderPass. This will sync a tile to blender. and call the `RE_engine_end_result`; what will sync the tile result back to the full image (`render_result_merge). The render API has an option to only update a section of the display based on a given rect. The display update is set to `image_rect_update` when rendering. This function taggs the image with a `IMA_GPU_REFRESH` and marks the `GPUTexture` of the image as obsolete. The next time the `GPUTexture` is used/requested a new `GPUTexture` is created. During this creation process the image is scaled to match the size of the `GPUTexture`. If the image does not fit on the GPU it is scaled down. We could add partial updates of GPUTextures so only the new data needs to be scaled (`IMA_GPU_PARTIAL_REFRESH`). the rects that needs to be refreshed could be hold in a list on the `ImBuf`. NOTE: `IMA_GPU_PARTIAL_REFRESH` can be promoted to `IMA_GPU_REFRESH`. There is already a function that can update a part of a GPU texture `IMB_update_gpu_texture_sub`. But there is room for improvement here. as it uses `imb_gpu_get_data` that still converts and scales the full image. ## Proposed solution * Modify `IMB_update_gpu_texture_sub` to be able to update a part of the source image. Currently it copies the full source image to a defined part on the GPUTexture. ** Create `imb_gpu_get_sub_data` that is similar to `imb_gpu_get_data` but doesn't convert/scale the full image. Use this function in. * Add `IMA_GPU_PARTIAL_REFRESH` ** change `image_rect_update` to use `IMA_GPU_PARTIAL_REFRESH` * Keep track of parts of the image that needs to be refreshes. I would start with a linked list as that is more scalable when rendering on 64 cores.

Added subscriber: @brecht

Added subscriber: @brecht

That sounds good to me. It may be possible to reuse the existing code for texture painting that does partial updates of scaled and unscaled textures.

That sounds good to me. It may be possible to reuse the existing code for texture painting that does partial updates of scaled and unscaled textures.
Member

Yes gpu_texture_update_from_ibuf handles this for texture painting. During development we should consider to merge the two implementations

Yes `gpu_texture_update_from_ibuf` handles this for texture painting. During development we should consider to merge the two implementations

Added subscriber: @fclem

Added subscriber: @fclem

Sounds good to me too. Although, this would not help when using progressive refine. But I think this is an edge case as it's not used often.

Sounds good to me too. Although, this would not help when using progressive refine. But I think this is an edge case as it's not used often.
Jeroen Bakker self-assigned this 2020-11-18 07:19:00 +01:00

Added subscribers: @Slowwkidd, @lichtwerk, @YAFU, @rjg

Added subscribers: @Slowwkidd, @lichtwerk, @YAFU, @rjg

Just to leave a comment to be sure, I encountered the same problem in 2.91 with a resolution of 1754x2481, not "very high", so I guess the bug regards also smaller resolutions than the one in the first report.

@Jeroen-Bakker Shouldn't this be considered a high priority? It considerably increases the render times for renders around 2K resolution, which is a quite common scale for renders, and it's currently present in 2.91.

Just to leave a comment to be sure, I encountered the same problem in 2.91 with a resolution of 1754x2481, not "very high", so I guess the bug regards also smaller resolutions than the one in the first report. @Jeroen-Bakker Shouldn't this be considered a high priority? It considerably increases the render times for renders around 2K resolution, which is a quite common scale for renders, and it's currently present in 2.91.
Contributor

Added subscriber: @Raimund58

Added subscriber: @Raimund58

Added subscriber: @silex

Added subscriber: @silex

After https://developer.blender.org/rB2e1498ff16198742ba543004fd9c2c49083a6095 patch I'm no longer experiencing crashes with rendering which is nice.
I've done some tests on current build hash 010f44b855 branch master.
The bigger the render image size the bigger the performance hit.

rendering image size / average CPU usage
3000x3000 / ~98%
6000x6000 / ~ 90%
9000x9000 / ~ 70%
12000x12000 / ~ 2%

Cycles CPU rendering, tile size 32px. No adaptive sampling or denoising.

After https://developer.blender.org/rB2e1498ff16198742ba543004fd9c2c49083a6095 patch I'm no longer experiencing crashes with rendering which is nice. I've done some tests on current build hash 010f44b855ca branch master. The bigger the render image size the bigger the performance hit. rendering image size / average CPU usage 3000x3000 / ~98% 6000x6000 / ~ 90% 9000x9000 / ~ 70% 12000x12000 / ~ 2% Cycles CPU rendering, tile size 32px. No adaptive sampling or denoising.
Member

@silex have you tried after applying the patch of this task?

@silex have you tried after applying the patch of this task?

This issue was referenced by 4f9e21bdc9

This issue was referenced by 4f9e21bdc9772603acc0ba6727da9dd67287ac0f
Member

Changed status from 'Confirmed' to: 'Resolved'

Changed status from 'Confirmed' to: 'Resolved'

Thank you!
After quick test the CPU looks fully utilised in all above scenarios.
As for exact performance numbers I'll need to check out. Nevertheless most regression seems to be gone.

Thank you! After quick test the CPU looks fully utilised in all above scenarios. As for exact performance numbers I'll need to check out. Nevertheless most regression seems to be gone.

I've run some tests and it seems that regression is happening in hybrid CPU+GPU rendering also.
Unfortunately I cannot pinpoint exact scene config for solid example.
Default cube renders without regression, but on production scenes with heavy geometry with displacement, volumes and lots of lights (both emissive mesh and standard) I have dips to 0% CPU utilisation.
2021-01-09_21-41.png
CPU-only rendering regression is fixed.

Additionaly the tile size is wrong. In properties tile size is set to 32 px, and during rendering tile is around 14x14 px:
tiles.png

I've run some tests and it seems that regression is happening in hybrid CPU+GPU rendering also. Unfortunately I cannot pinpoint exact scene config for solid example. Default cube renders without regression, but on production scenes with heavy geometry with displacement, volumes and lots of lights (both emissive mesh and standard) I have dips to 0% CPU utilisation. ![2021-01-09_21-41.png](https://archive.blender.org/developer/F9557484/2021-01-09_21-41.png) CPU-only rendering regression is fixed. Additionaly the tile size is wrong. In properties tile size is set to 32 px, and during rendering tile is around 14x14 px: ![tiles.png](https://archive.blender.org/developer/F9558406/tiles.png)
Member

Added subscriber: @Luan-Rodrigues

Added subscriber: @Luan-Rodrigues
Sign in to join this conversation.
No Label
Interest
Alembic
Interest
Animation & Rigging
Interest
Asset Browser
Interest
Asset Browser Project Overview
Interest
Audio
Interest
Automated Testing
Interest
Blender Asset Bundle
Interest
BlendFile
Interest
Collada
Interest
Compatibility
Interest
Compositing
Interest
Core
Interest
Cycles
Interest
Dependency Graph
Interest
Development Management
Interest
EEVEE
Interest
EEVEE & Viewport
Interest
Freestyle
Interest
Geometry Nodes
Interest
Grease Pencil
Interest
ID Management
Interest
Images & Movies
Interest
Import Export
Interest
Line Art
Interest
Masking
Interest
Metal
Interest
Modeling
Interest
Modifiers
Interest
Motion Tracking
Interest
Nodes & Physics
Interest
OpenGL
Interest
Overlay
Interest
Overrides
Interest
Performance
Interest
Physics
Interest
Pipeline, Assets & IO
Interest
Platforms, Builds & Tests
Interest
Python API
Interest
Render & Cycles
Interest
Render Pipeline
Interest
Sculpt, Paint & Texture
Interest
Text Editor
Interest
Translations
Interest
Triaging
Interest
Undo
Interest
USD
Interest
User Interface
Interest
UV Editing
Interest
VFX & Video
Interest
Video Sequencer
Interest
Virtual Reality
Interest
Vulkan
Interest
Wayland
Interest
Workbench
Interest: X11
Legacy
Blender 2.8 Project
Legacy
Milestone 1: Basic, Local Asset Browser
Legacy
OpenGL Error
Meta
Good First Issue
Meta
Papercut
Meta
Retrospective
Meta
Security
Module
Animation & Rigging
Module
Core
Module
Development Management
Module
EEVEE & Viewport
Module
Grease Pencil
Module
Modeling
Module
Nodes & Physics
Module
Pipeline, Assets & IO
Module
Platforms, Builds & Tests
Module
Python API
Module
Render & Cycles
Module
Sculpt, Paint & Texture
Module
Triaging
Module
User Interface
Module
VFX & Video
Platform
FreeBSD
Platform
Linux
Platform
macOS
Platform
Windows
Priority
High
Priority
Low
Priority
Normal
Priority
Unbreak Now!
Status
Archived
Status
Confirmed
Status
Duplicate
Status
Needs Info from Developers
Status
Needs Information from User
Status
Needs Triage
Status
Resolved
Type
Bug
Type
Design
Type
Known Issue
Type
Patch
Type
Report
Type
To Do
No Milestone
No project
No Assignees
10 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: blender/blender#82591
No description provided.