[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Public WebGL] WebKit 20-50% slower than Chrome/Minefield using large Float32Array Arrays
- To: Thatcher Ulrich <tu@tulrich.com>
- Subject: Re: [Public WebGL] WebKit 20-50% slower than Chrome/Minefield using large Float32Array Arrays
- From: Steve Baker <steve@sjbaker.org>
- Date: Thu, 17 Feb 2011 08:22:55 -0600
- Cc: Stephen Bannasch <stephen.bannasch@deanbrook.org>, public_webgl@khronos.org
- Dkim-signature: v=1; a=rsa-sha1; c=relaxed; d=sjbaker.org; h=message-id :date:from:mime-version:to:cc:subject:references:in-reply-to :content-type:content-transfer-encoding; s=sjbaker.org; bh=WezYm mEEH12v4M6Ki5/kfmOxQYk=; b=WMbXBqobpWLBzAf3DslnMkplkrFdNNHqB+/q+ UDY69wXiskeMVYMuiwF7a06uINKlXHk5ZhS3p6NKthh2zAhk/qkG3KZ/TrSkW5oy LEwf9S/7r40oiyDRp1i0oD3JioA4E3IzNBkatymVuAVASyQeyo86v4eyrpMt21SD nlFi2o=
- Domainkey-signature: a=rsa-sha1; c=nofws; d=sjbaker.org; h=message-id:date :from:mime-version:to:cc:subject:references:in-reply-to :content-type:content-transfer-encoding; q=dns; s=sjbaker.org; b=IxiWYn1+L82/WI32R7c8p5e/2vQhT9xYuAu9rJETNOr6bfwQFNm0vErPVupNh GN2rQh3gtf8cJkAQy5XZg30SSo2d7pLK6DCNrZ3MNQd/SqPIzFC1A5Mv+bVdiX7I oJuER30C3ktrVMy5TfVnIQUmiZtE+V6BJPkQ2YKTwXQG68=
- In-reply-to: <AANLkTin8wKjQyMTBANmRRoteKRmNtwD4VcBetzFX0RMu@mail.gmail.com>
- List-id: Public WebGL Mailing List <public_webgl.khronos.org>
- References: <p06240816c98262b859ca@192.168.1.122> <AANLkTin8wKjQyMTBANmRRoteKRmNtwD4VcBetzFX0RMu@mail.gmail.com>
- Sender: owner-public_webgl@khronos.org
- User-agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.10) Gecko/20100520 SUSE/3.0.5 Thunderbird/3.0.5
If there was ever a job for the GPU, this is it!
I've done this kind of thermal simulation in the GPU in the past - and
the results were pretty good. (I used to do simulation of thermal
imaging in military IR cameras - and we needed to simulate the thermal
consequences of an explosion).
Make the grid into a texture map - write a shader that takes the last
iteration's raw data as a texture map and generates one cell of the
output from it...that would require porting your thermal calculations
into GLSL - but I'd be surprised if that was hard. Then you can
compute the entire update by drawing a single quadrilateral to a second
texture/FBO. If the calculation part is really complex, you might need
to break it into several stages and do each one in a separate rendering
pass...but it's hard to imagine that this would be difficult.
If you need to do it in 3D then pass a number of adjacent 2D slices as
textures into a shader that computes a 2D slice as output...you then
draw one 2D slice with each quadrilateral you draw - but you can do all
of that in a single draw call.
When you have the calculated result, you can do the false-color
rendering of the resulting raw data with a second shader that uses a 1D
texture map to convert temperature to color.
The trick is to make sure that the data never leaves the GPU - do all of
your storage with textures/FBO's and all of your calculations and
display in GLSL.
Because the S-L-O-W JavaScript code is now running as a GLSL program in
the mind-blowingly fast GPU, I bet you could get the raw frame rate for
a 3D case up to maybe a hundred hertz...much faster than you can display
it. This enables you to use much smaller time-steps - which reduces
the velocities and that drastically improves the parts of the
calculation that tend towards numerical instability (advection was the
worst culprit IIRC).
-- Steve
On 02/17/2011 04:23 AM, Thatcher Ulrich wrote:
> Cool demo.
>
> One thing you should try, without even going to WebGL, is filling the
> canvas using context.putImageData() instead of lots of fillRect calls.
> Perhaps also best to render into a 100x100 canvas, and have the
> browser scale it onto the correct size on the page, instead of doing
> that in your paint routine. Though I think the scaling will be smooth
> instead of blocky; not sure if you want that.
>
> The other thing you should definitely do is make a color table instead
> of making and parsing "hsl(...)" strings for every pixel.
>
> Code (untested, edited from yours) would look something like:
>
> model2d.displayTemperature = function(canvas, model) {
> var ctx = canvas.getContext('2d');
> ctx.fillStyle = "rgb(0,0,0)";
> ctx.globalCompositeOperation = "destination-atop";
>
> // Set the CSS width/height to the desired display height.
> // Better to just do this in the HTML on the page using the
> // style attribute.
> canvas.style.width = canvas.clientWidth + 'px';
> canvas.style.height = canvas.clientHeight + 'px';
>
> // Force the actual source pixel data to be 100x100.
> canvas.width = 100;
> canvas.height = 100;
>
> var hue;
> var rgb;
>
> var columns = model.nx;
> var rows = model.ny;
> var ycols, ycols_plus_x;
>
> var t = model.t;
> var min = model2d.getMinTypedArray(t);
> var max = model2d.getMaxTypedArray(t);
> var scale = 255/(max - min);
> var temp;
> var imdata = ctx.getImageData(0, 0, 100, 100);
> var data = imdata.data;
> for (y = 0; y < rows; y++) {
> ycols = y * rows;
> var pix_index = y * 100;
> for (x = 0; x < columns; x++) {
> ycols_plus_x = ycols + x;
> temp = model.t[ycols_plus_x];
> hue = Math.abs(Math.round(scale * temp - min) - 255);
> // Assume a pre-computed color table!
> rgb = color_table[Math.min(Math.floor(hue + 0.5), 255)];
> data[pix_index] = rgb.r;
> data[pix_index + 1] = rgb.g;
> data[pix_index + 2] = rgb.b;
> data[pix_index + 3] = rgb.a;
> pix_index += 4;
> }
> }
> ctx.putImageData(imdata, 0, 0);
> }
>
> -T
>
> On Thu, Feb 17, 2011 at 6:42 AM, Stephen Bannasch
> <stephen.bannasch@deanbrook.org> wrote:
>
>> Here's a test using large Float32Array Typed Arrays (many sized 100x100)
>> where WebKit ends up 20-50% slower than Chrome and Minefield. In these tests
>> Minefield edges out Chrome but not by much.
>>
>> I found that 90% of the time was spent rendering the false-color thermal map
>> graphics.
>>
>> Suggestions for how to speed this up would be great.
>>
>> I created an initial port of our Java Energy2D application running in
>> JavaScript. The backing model is doing a thermal simulation of conductivity,
>> convection, and radiation with 10,000 cells.
>>
>> http://visual-demos.dev.concord.org/seasons/earth/model2d.html
>>
>> The JavaScript implementation uses JavaScript Typed Arrays so it only works
>> with browsers that supports WebGL (Chrome 9, recent FireFox betas, and
>> WebKit nightlies).
>>
>> The original Java version of Energy2D can be seen here:
>> http://energy.concord.org/energy2d/index.html
>>
>> The JavaScript simulation model starts with a fixed high-temperature spot in
>> the middle.
>>
>> The basic model simulation space is a 100x100 grid, 10,000 cells the same as
>> the Java version of Energy2D.
>>
>> The JavaScript code is here:
>> https://github.com/stepheneb/seasons/blob/master/earth/model2d.js
>>
>> I'm getting about 4 model iterations/s on Chrome and FF betas, and about 3
>> on WebKit/Safari.
>>
>> I wondered how much of the time was doing graphics and how much was running
>> the model ... turns out a huge bottleneck is rendering the graphics.
>>
>> The demo page renders the false-color thermal map with one of two
>> techniques: using HTML5 Canvas, or stuffing 10,000 styled divs using
>> innerHTML. I was surprised when the two methods ended up practically
>> equivalent in time.
>>
>> I'd like to find a much quicker way to render the graphics ... perhaps using
>> WebGL.
>>
>> I'm very impressed at how fast the model calculation runs.
>>
>> My tests below run the model for 15s on my MacOS X 10.6.6 PowerBook Pro with
>> a 2.66 GHz Intel Core i7.
>>
>>
>> Rendering to both the canvas visualization and the table of data:
>>
>> Browser model steps model steps/s
>> --------------------------------------------------------------------
>> Chrome v9.0.597.102 59 3.9
>> Minefield 4.0b12pre (2011-02-16) 60 4.0
>> WebKit v5.0.3 (6533.19.4, r78685) 48 3.2
>>
>>
>> Rendering just to the canvas visualization:
>>
>> Browser model steps model steps/s
>> --------------------------------------------------------------------
>> Chrome v9.0.597.102 68 4.5
>> Minefield 4.0b12pre (2011-02-16) 84 5.6
>> WebKit v5.0.3 (6533.19.4, r78685) 64 4.3
>>
>>
>> With rendering to the canvas and the table of data disabled:
>>
>> Browser model steps model steps/s
>> --------------------------------------------------------------------
>> Chrome v9.0.597.102 489 32.6
>> Minefield 4.0b12pre (2011-02-16) 507 33.8
>> WebKit v5.0.3 (6533.19.4, r78685) 220 14.7
>>
>> What is speeding this up is the use of JavaScript Typed Arrays:
>>
>> http://www.khronos.org/registry/typedarray/specs/latest/
>>
>> This capability is associated with browsers that have implemented WebGL but
>> none of the JavaScript Energy2D code is actually running on the GPU. The
>> speedup is because of optimizations the JavaScript engines can make with
>> math when working with fixed length arrays and one kind of number.
>>
>>
>> -----------------------------------------------------------
>> You are currently subscribed to public_webgl@khronos.org.
>> To unsubscribe, send an email to majordomo@khronos.org with
>> the following command in the body of your email:
>> unsubscribe public_webgl
>> -----------------------------------------------------------
>>
>>
>>
> -----------------------------------------------------------
> You are currently subscribed to public_webgl@khronos.org.
> To unsubscribe, send an email to majordomo@khronos.org with
> the following command in the body of your email:
> unsubscribe public_webgl
> -----------------------------------------------------------
>
>
-----------------------------------------------------------
You are currently subscribed to public_webgl@khronos.org.
To unsubscribe, send an email to majordomo@khronos.org with
the following command in the body of your email:
unsubscribe public_webgl
-----------------------------------------------------------