Live data from Hacker News

How Discord Resizes 150M Images Every Day with Go and C++

blog.discordapp.com

141–150 of 157 posts

Re: How Discord Resizes 150M Images Every Day with Go and C++

#141
post #115

I wonder why people implement such things on CPU? PCI express is ~100 gbit/sec, much faster than any network interface. Internally, a GPU can resize these images by an order of magnitude faster than that, see the fillrate columns in the GPU spec.

This isn't just resampling an image: decoding a variety of image (and even video) formats, decompressing the selected frame, performing the actual resize, and then compressing the result. If the resample doesn't save more than the setup overhead, it'd be an immediate loss. Even if it does, there's an engineering cost since you now need to make sure that all of your servers have GPUs available, your chosen implementat…

> This isn't just resampling an image

GPUs can do that, too: http://fastcompression.com/products/jpeg/cuda-jpeg.htm

> you now need to make sure that all of your servers have GPUs available

OP is running on google’s cloud: “n1-standard-16 host type, peaking at 12 instances on a typical day.” That instance costs $0.76/hour. Adding NVIDIA Tesla K80 is $0.7 extra.

> it's really tempting not to deal with any of that

Yeah, that’s understandable. But the original article dealt with a lot of strange technologies to get the performance they want. And ended up doing much slower, performance wise, than what’s possible with a GPU.

Re: How Discord Resizes 150M Images Every Day with Go and C++

#142
post #115

Earlier quoted context omitted.

This isn't just resampling an image: decoding a variety of image (and even video) formats, decompressing the selected frame, performing the actual resize, and then compressing the result. If the resample doesn't save more than the setup overhead, it'd be an immediate loss. Even if it does, there's an engineering cost since you now need to make sure that all of your servers have GPUs available, your chosen implementat…

> This isn't just resampling an image GPUs can do that, too: http://fastcompression.com/products/jpeg/cuda-jpeg.htm > you now need to make sure that all of your servers have GPUs available OP is running on google’s cloud: “n1-standard-16 host type, peaking at 12 instances on a typical day.” That instance costs $0.76/hour. Adding NVIDIA Tesla K80 is $0.7 extra. > it's really tempting not to deal with any of that Yeah,…

We did consider doing GPU, but it seems like you have fewer options there. We were really picky about the resize kernel used and it seems like with GPU you may not always get the same kernels available. Also presumably that only handles resizing, not compressing/decompressing, which make up a pretty sizeable portion of the workload.

Re: How Discord Resizes 150M Images Every Day with Go and C++

#143
post #61

Earlier quoted context omitted.

agree on 3) most browsers just use linear interpolation when resizing images, which makes sense from a performance point of view, but looks terrible. Better to use a bi-linear or cubic resize, more computing up front, but better images, this is probably the reason they do it

bi-linear is linear interpolation

I think they may have meant "nearest-neighbor", which isn't true for any browsers that I know of.

Regardless, there are still better filters than bilinear, i.e. Lanczos, which I'm pretty sure none of the browsers use.

Re: How Discord Resizes 150M Images Every Day with Go and C++

#144

Earlier quoted context omitted.

> This isn't just resampling an image GPUs can do that, too: http://fastcompression.com/products/jpeg/cuda-jpeg.htm > you now need to make sure that all of your servers have GPUs available OP is running on google’s cloud: “n1-standard-16 host type, peaking at 12 instances on a typical day.” That instance costs $0.76/hour. Adding NVIDIA Tesla K80 is $0.7 extra. > it's really tempting not to deal with any of that Yeah,…

We did consider doing GPU, but it seems like you have fewer options there. We were really picky about the resize kernel used and it seems like with GPU you may not always get the same kernels available. Also presumably that only handles resizing, not compressing/decompressing, which make up a pretty sizeable portion of the workload.

> with GPU you may not always get the same kernels available

No kernels are available _out of the box_. You code a pixel shader, implement any kernel, or any other resizing method besides kernels: https://stackoverflow.com/a/42179924/126995

> that only handles resizing, not compressing/decompressing

In my previous comment there’s a link to a commercially available JPEG codec, 100% compliant with JPEG Baseline Standard, that does both compression and decompression.

Re: How Discord Resizes 150M Images Every Day with Go and C++

#145

Earlier quoted context omitted.

We did consider doing GPU, but it seems like you have fewer options there. We were really picky about the resize kernel used and it seems like with GPU you may not always get the same kernels available. Also presumably that only handles resizing, not compressing/decompressing, which make up a pretty sizeable portion of the workload.

> with GPU you may not always get the same kernels available No kernels are available _out of the box_. You code a pixel shader, implement any kernel, or any other resizing method besides kernels: https://stackoverflow.com/a/42179924/126995 > that only handles resizing, not compressing/decompressing In my previous comment there’s a link to a commercially available JPEG codec, 100% compliant with JPEG Baseline Standar…

Yikes. If we had had to write our own image resizing kernel, this would have taken much longer. And ok, it can do JPEG but what about PNG, GIF, and WEBP?

Re: How Discord Resizes 150M Images Every Day with Go and C++

#146
post #61

Earlier quoted context omitted.

A few reasons: 1) Although the site serves up images at 1024 pixels (or whatever) today, in the future they may want larger images. When everyone is rocking 10K monitors and 6K phone displays, those small images are going to look pretty bad. 2) The original image has some metadata that they want to keep (geolocation, etc). 3) They think they can do a better and more consistent job resizing than the various browsers,…

agree on 3) most browsers just use linear interpolation when resizing images, which makes sense from a performance point of view, but looks terrible. Better to use a bi-linear or cubic resize, more computing up front, but better images, this is probably the reason they do it

If you resize the image in steps, with each resize at least 50% of the previous step, you can do a pretty decent approximation of cubic resize using the canvas. Doing this for a year now, we've gotten no complaints and we have designers as clients :)

Re: How Discord Resizes 150M Images Every Day with Go and C++

#147

Earlier quoted context omitted.

> with GPU you may not always get the same kernels available No kernels are available _out of the box_. You code a pixel shader, implement any kernel, or any other resizing method besides kernels: https://stackoverflow.com/a/42179924/126995 > that only handles resizing, not compressing/decompressing In my previous comment there’s a link to a commercially available JPEG codec, 100% compliant with JPEG Baseline Standar…

Yikes. If we had had to write our own image resizing kernel, this would have taken much longer. And ok, it can do JPEG but what about PNG, GIF, and WEBP?

> If we had had to write our own image resizing kernel, this would have taken much longer

I don’t disagree but this is very subjective.

You don’t need to invent anything, you only need to carefully implement a well known approach, e.g. this one: https://developer.nvidia.com/gpugems/GPUGems/gpugems_ch24.ht...

Also there’re third party libraries for that, e.g. here’s one from the same company who do JPEG codec: http://fastcompression.com/products/resizer/gpu-resizer.htm

> what about PNG, GIF, and WEBP?

As far as I understand, you goal was to cut server costs, right?

I assume the majority of pictures on the Internet are jpegs. If you have them processing on the GPU, this leaves you 16 virtual CPUs you’ve already paid for just sitting idle and waiting for the GPU to finish the job. No need to do everything on GPU.

P.S. Some other people already implemented what I’m telling you: http://code.flickr.net/2015/06/25/real-time-resizing-of-flic...

Re: How Discord Resizes 150M Images Every Day with Go and C++

#148

Why don't more companies resize images client-side first using and then save the server some work by only asking it to verify the result by - resizing to the same size - removing metadata This results in much faster transfer (10x less bandwidth used often for mobile uploads) and reduces server load by "farming" out the work to the clients. https://developer.mozilla.org/en-US/docs/Web/API/CanvasRende... # Edit: On Kee…

isn't it a meme at this point, pushing computational work to the client side? I have a laptop or mobile device, please don't hog my limited cpu and battery life by forcing my device to resize images.

Are you sure your wifi connection will not eat more power with huge upload than processor/gpu doing the scaling?

Re: How Discord Resizes 150M Images Every Day with Go and C++

#150

Earlier quoted context omitted.

The downvotes are also because it's a somewhat cliche comment on HN now. Anytime anyone is doing any with C or C++ that is even indirectly web facing, "this could be unsafe!!!" is an obligatory comment, even though all major tech companies have core components written in C++, and there are big web apps that have been running for years that are mostly written in C or C++. Security is definitely a concern, but these ki…

This isn’t one of those. Handing large amounts of unvalidated user input to these libraries is particularly dangerous.

Where is the assumption coming from that it hasn't been validated?
Post reply on HN