Cycles - separate render tile sizes - CPU and GPU
GPU performance seems sub-optimal on my rig in CPU+GPU OpenCL rendering. Most of the post is written with the assumption that separating CPU & GPU tile sizes is the solution.
TLDR; I wish there were a separate CPU and GPU tile size setting for Cycles rendering. Optimization could be (possibly in order of desirability) - assumes GPU tiles are always equal to or bigger than CPU tiles:
- extremely simple: no CPU tiles left, no CPU rendering; no GPU tiles left, no GPU rendering
- custom: give us a separate tile x+y size for CPU and GPU, give us a max # of tiles either CPU or GPU renders (0 = no optimization), and have the user figure out what's close to optimum
- more optimized: once GPU sized tiles are rendered, GPU renders CPU sized tiles - could be a terrible idea. See 16x16 GPU time in chart below... But with my setup the one GPU is still faster than 1C/2T so probably okay?
- fully optimized: calculate/guesstimate whether GPU or CPU or shared would be faster near the end, based on previous tiles (and perhaps in animation, previous render?); may include GPU rendering tiles sized between max/GPU and min/CPU. Could get very complicated, developer time probably best spent elsewhere
It may be best to force max/GPU tile X and tile Y to be multiples of min/CPU tile X and tile Y.
Story time: I recently did a 50 hour 900 frame 1920x1080 animation render on my PC (R9 3900X - 12C/24T and Radeon VII) and was disappointed to see that whenever I checked the task manager (in windows 10) the GPU was using less than 10% and most of the time 5% or less. This seems to indicate a lot of performance still being left on the table. (in Blender 2.81)
When I saw a Blender Guru report (I believe a youtube movie along the lines of "20/25 tips for faster rendering") comparing tile sizes for CPU, GPU and CPU+GPU I decided to do some testing on my own rig:
Blender 2.80, Windows 10 Pro
CPU (AMD R9 3900X (12C/24T))
Tile Size .Memory Peak(MB) .Time (sec)
. .16 . . . . .2623 . . . . . .67
. .64 . . . . .2626 . . . . . .68
. 256 . . . . .2668 . . . . . .91
GPU (AMD Radeon VII)
Tile Size .Memory Peak(MB) .Time (sec)
. .16 . . . . .4529 . . . . . 460
. .64 . . . . .4529 . . . . . .70
. 256 . . . . .4531 . . . . . .52
CPU+GPU (3900X + VII)
Tile Size .Memory Peak(MB) .Time (sec)
. .16 . . . . .2611 . . . . . .65
. .32 . . . . .2611 . . . . . .54
. .64 . . . . .2611 . . . . . .43
. 128 . . . . .2611 . . . . . .45
. 256 . . . . .2611 . . . . . .94
Perhaps it's not a reasonable expectation but I feel as though the combined CPU+GPU method should be able to render in under - or at most around - 34 seconds.
I've only been blendering for under 4 months so please let me know if I left anything out or made some crazy assumptions. Thanks for your time.
30 Comments
So I managed to briefly get my hands on an Nvidia system (I spent my Blender class doing testing), and tested my old system as well, for comparison. The tests (this time) were done with the Car Demo from the Blender Demo Downloads . I used the CPU file and set CUDA/OpenCL preferences, and tile sizes when appropriate. I didn't have time left - nor the foresight - to test OpenCL on the Nvidia system. OpenCL has a caching time the first time you use it; this is not counted in any of the results.
* @Jason van Gumster * sidenote: the code block markdown really shouldn't trim multiple spaces. Probably not under your purview but there you have it.
* @Josephbburg * You wanted a reminder to have and/or do more testing?
* @Ken Vannen * I wanted to help testing because I have a CUDA card. I'm not sure it's really necessary now! I am using a Linux, though, so maybe that would be good for comparison.
Also, it looks like slow GPU performance for small tiles has not in fact been fixed.
* @Josephbburg * Actually a straight Nvidia Cuda vs Nvidia OpenCL might be more telling than all the testing I've done, if you feel up to it.
* @Ken Vannen * I hope I'll have time during the week. I need to make a rigging video today, and I have some client work I've been putting off ...
* @Josephbburg * If not, I might have a final chance to do so next week. Although it feels a bit weird doing nothing but hardware tests in Blender class...
* @Ken Vannen * You have a class for Blender? Where? I had to teach myself!
* @Josephbburg * Local technical school. The teacher's a hobbyist but fortunately he doesn't mind being 'overshadowed'. If anything, the thought of it gets him giddy, and excited to learn more himself.
I've probably learned more from Youtube than the class. Somehow I've generally managed to learn a lesson's contents a week or two before the actual class. What I wanted most from the class was to be 'forced' to be busy with Blender once a week, and some structure to the learning at the very beginning.
Between free tutorials at e.g. Youtube, paid tutorials at e.g. Udemy, Skillshare, Lynda, and great online Blender communities one has to wonder if you've missed all that much, if anything.
* @Ken Vannen * I'm in a university in the USA (it's considered the best public university for animation, actually), and the same is honestly true of me. I've learned more from youtube and forums than anything else, and most of what I'm doing in Maya is well beyond the scope of the class. I suppose that means I'm in a good position to find work! Anyways, knowing Blender made it really easy to get into, but Maya has also been really dissapointing -- it's missing a lot of things I took for granted before. My 3D cursor :'( my BENDY BONES!
* @Josephbburg * As I understand, Maya's strengths are enterprise level support - so Blender could do something akin to Red Hat does with Linux e.g. Priority Support & Feature Requests - as well as the mere fact that it's been used for ages. Meaning it's entrenched by valuable artist experience and expensive pipeline/app/addon developments.
As for Nvidia OpenCL testing, that was a wash. The Nvidia GTX 750 Ti doesn't support OpenCL rendering. I also found blender open data , official test results from the offical testing suite - both things I didn't know existed before. However I find it a bit difficult to get the overviews I want and it is devoid of any kind of hybrid CPU+GPU testing. I imagine it could be insightful to the Blender organization to know how well CPU+GPU scales compared to exclusively CPU and exclusively GPU.
Also I didn't know hybrid CPU+GPU rendering is new with 2.80, so perhaps it's to be expected that I'm a little underwhelmed since both hybrid and OpenCL rendering is so new to blender. In other words I'm now doubting whether the situation merits further efforts from me.
This idea has been tossed around a few times, and I love the idea, but the BF won't be doing anything like that, since they're a non-profit. Maybe something like this can be included in Blender Cloud someday. But I've thought about getting into this business myself many times. It could be invaluable to funding my artistic ambitions!
Hm maybe in your case better render by console, have one batch render CPU from end to start, and GPU from start to end.
* @peter.boos * That's certainly an alternative I hadn't considered. It's only feasible for animations but you could indeed render e.g. 360 frames on CPU and 540 frames on GPU (40-60) and hope you're more or less optimal. Assuming there's no cache mix-ups with opening/rendering the same file twice that could work fairly well. Although I do prefer automatic things over manual ones.
Why is the by console part important?
* @Ken Vannen * Rendering by console isn't overly necessary, but you will see a performance increase if you render from the command line versus rendering from the GUI... even if you're only using one instance of Blender.
* @Ken Vannen * You can use the console to have Cycles mix the results of the two renders automatically. It's pretty simple to use Python to do it with
import subprocess* @Jason van Gumster * Interesting. Is this performance increase sizeable? Is this performance increase a Windows-only thing or also noticeable under Linux?
* @Josephbburg * Interesting. I'll have to see how desirable it is for my circumstances, once I find some time.
* @Ken Vannen * If you're rendering animations or large images, the performance increase is measurable. It's not on the order of half the time or anything (I've had render jobs finish in 5-15% of their time)... but every little bit helps.
This is a known thing that's true across all platforms. I haven't fully tested this but in Blender 2.8, I think you can get similar results if you go to Preferences→Interface→Editors→Temporary Windows and set the Render In option to "Keep User Interface".
* @Ken Vannen * Here's a script I wrote for batch-rendering with Appleseed Renderer Standalone, it should be easy to modify it to Cycles (you'd be calling the Blender executable with the rendering information. Parsing strings like this is tedious! But less tedious than rendering each frame by hand. And of course, Blender can batch render directly- you could use this kind of script to line up multiple .blends for rendering without having to use something like Flamenco.
* @Ken Vannen * Its not important, but if you want rendering to be slightly faster you can do it by console (no need to render GUI). If you need to render often it also might be more easily scriptable (by batch, vbscript / python / batch ). I used to render like that in the past when i worked at another company there i had multiple systems and wrote a vbscript that checked which frames to (re) render. (unfortunately i didn't took the script with me when i left there).
Duplicate of this proposal .
* @Jason van Gumster * So it is. I did a search for "Cycles tile" but forgot there was no reason to specify Cycles before summer 2019.
That said the OP commented his issue as closed (I don't think it was closed as a topic) whereas I feel this is still an active issue, at least with my AMD GPU using OpenCL.
What's the Right-Click Select netiquette? Now that it's a duplicate, do I continue on briecmuldoon's proposal or here on my own?
* @Ken Vannen * In an ideal world, the discussion would push over to the first proposal and this one would be locked. Unfortunately, those facilities don't yet exist in this site's backend. In this particular case, maybe it makes more sense to archive that other proposal and mark this one as the open one. I'll go ahead and do that now.
From what I understand, the GPU tiles affecting speed was considered a bug and should have been fixed (Should produce same speed regardless of tile size). I thought this was no longer the case in 2.80. Could be slow for you because you're using an AMD card with OpenCL.
I think the plan for fixing this problem is actually to add work-stealing at some point-- i.e, the GPU will take the render job from the CPU if it can improve speed by taking over.
* @Josephbburg *
I'm afraid I don't follow. In OpenCL the graphics card is one tile, same size as tile size. So in mixed CPU+GPU rendering, with my 24 thread CPU, I have 25 tiles one of which (the GPU, I assume) renders over 4 times as fast as the CPU cores at 64x64 tile size. Are you saying in Cuda/OptiX the GPU(s) simply ignore tile size and... do a sample at a time for the entire image, or some such?
That seems optimal near the end of the image. Most of my suggestion comes before that, and really only applies to shared CPU+GPU workloads. My GPU is fastest (or just about) with 256x256 tiles. The CPU is fastest (or just about) with 16x16 tiles. The default 64x64 tile is an okay middle ground but the CPU could be slightly faster and my GPU could - in the example above - be at least 33% faster or 25% shorter render time. * For the GPU render times which I estimate would here be ~60% of the work? So 20% faster or 15% shorter in my mixed CPU+GPU mode.
In hindsight perhaps I'd better bought a RTX 2070 super for the money but at least in my situation there's quite a lot of performance to be had with probably little dev time.
* @Ken Vannen * The GPU should have similar performance regardless of tile size, that's the bug I was referring to. It's been fixed for CUDA, AFAIK. I don't think it's possible to have different sized tiles going at once.
* @Josephbburg *
I doubt it is possible, in Blender as it is now. I feel it's relatively easy to add though. Lazy design is to reserve the next N tiles for the GPU instead of the one. Better design might be to e.g. find a 256x256 'unworked' tile, reserve all 16x16 tiles in it, feed GPU a 256x256 tile. There are many roads to Rome.
Depending on what 'similar' means, that would be a solution. I don't see 'similar' performance in my charts, however. If the solution isn't a separate tile size, that's fine. I just detected a likely problem, used a topic title that seemed likely appropriate, and came to find more information. You're right that most of my OP is written under the assumption of that solution... Perhaps a short edit is in order.
By the way, I hope it doesn't sound like I'm pouncing on you. I'm grateful for your participation in this discussion.
I think a lot of the trouble will also be fixed when Adaptive Sampling finds its way to Cycles. There've been two different patches for this in Limbo for a while, and I think it's planned for release ~2.83 (the patch ). At any rate, Cycles is getting more and more love, and there's a dedicated developer for OpenCL, too. It might help to create some benchmarks and send the info over to the developer (I think it's Jeroen Bakker). If I get the time, remind me! I should see how my machine performs in CUDA/OpenCL. I can test it in Windows and Ubuntu.
* @Josephbburg * Adaptive Sampling sounds really, realy cool. I'm not knowledgeable enough to see why it would fix (part of?) this problem. The following comment from brecht is a bit worrying but couldn't find more info about it:
The release notes should at least clearly explain limitations regarding mixed device rendering.Is OpenCL still under development? I understand it to be backed exclusively by AMD; This BlenderNation post seems to indicate AMD wish their contribution to be focused on Vulkan support:
The firm was an active promoter of OpenCL for GPU computing,- possible typo, but using past tense.* @Ken Vannen * I was thinking that adaptive sampling would prevent tiles from taking forever and ever if they aren't important. I suppose it would only "solve" your problem by making total render time shorter.
I don't know the details of the funding, but I don't think it matters. There's enough money coming in without conditions that they can shuffle the work around for important features (and hardware support is an important feature). From what I understand, OpenCL has some major differences to CUDA in its design for how it manages multiple workers or chunks of data or something, so it might not even be a flaw in Blender's code that causes your issue. I don't think the port to Vulkan has happened yet, but maybe changing the graphics back-end will also improve compute shader performance? Who knows? Anyways, OpenCL's future is a little bit vague due to the OpenGL/Vulkan split, with its developer, Khronos, wanting to try to support both going forward. So I think it's one of those "lots of competing paradigms" situations that makes it hard to plan or do the right thing ahead of time. A bunch of projects have used OpenGL recently- it seems the same to me as all the people that stuck with Python 2.7 after 3.0 was introduced (OpenGL is Python 2, Vulkan is Python 3)... now there's a Python 2 and Python 3 version of everything and Python has officially ended support for Python 2.
* @Josephbburg * As I understand, adaptive sampling compares -per pixel- half the samples with all the samples. If 'close enough', it stops sampling. If a pixel hits 'min samples' without hitting 'close enough', all pixels around it must be worked until 'min samples'. Unsure why they called it 'min' samples because it never goes over so it acts like 'max samples'. After this they do some clever stuff to ensure denoising and such works as intended.
I don't give OpenGL much chance going forward. Vulkan is for new tech, OpenGL is almost exclusively for (increasingly) older tech. OpenGL is more implicit whereas Vulkan is more explicit. You ask OpenGL to do something whereas you tell Vulkan to do something. Vulkan has (far) longer setup and doesn't do anything automatically - because it doesn't assume any one thing is 'best' - but that can also be a strength and is often less buggy and faster. The main platform for OpenGL - or rather, OpenGL ES - was mobile, I thought, but iOS forces Metal API and Android has had Vulkan support since Android 7.0. Android 10 even runs OpenGL ES through Vulkan 1.1 . Also future versions of OpenCL past 2.2 will partially converge with Vulkan . In short I don't feel it's vague at all. You definitely still need OpenCL for legacy support but the way forward -industry wide- is quite clearly Vulkan.
After some sleuthing it appears Jeroen Bakker is indeed responsible for OpenCL although you could almost say Brecht Van Lommel is responsible for catching his communications. I guess I'll try to find some time on a few seperate PCs to gather some more data before contemplating contacting them.
There is a vague plan to make GPU render more than 1 tile. If I find proper info on it I'll post it here.
I made a proposal some time ago on devtalk: devtalk.blender.org/t/hardware-specific-rendering-bucket-size-cycles-cpu-gpu/8909
And a performance comparison on OpenCL regarding CPU and GPU: devtalk.blender.org/t/somewhat-comprehensive-radeon-vii-cycles-benchmark-opencl-linux/11671