Welcome to GitHub Pages.

Matrix Multiplication Test in WebGL

This demo shows the difference in performance between Javascript and gpu performance when naively multiplying some matrices.



// fragment shader that calculates the sum of the passed row and // column (texture coord). // we loop over the row and column and sum the product. // product is then rendered to 32-bit IEEE754 floating point in the // output RGBA canvas. // readPixel is used to read the bytes. #ifdef GL_ES precision highp float; #endif varying vec2 vTex; // row, column to calculate uniform sampler2D usampler; // left in .r, right in .g uniform int uLength; // r1xc1.r2xc2 => product has r2 (or c1) terms uniform float uStepS; // increment across source texture uniform float uStepT; // increment down source texture uniform float uOutRows; // size of output in rows uniform float uOutCols; // size of output in columns // sum row r x col c float sumrowcol(float row, float col) { float sum = 0.; // sum float ss = 0.; // column on source texture float tt = 0.; // row on source texture float r = row*uStepT; // moving texture coordinate float c = col*uStepS; // moving texture coordinate for (int pos=0 ; pos<2048 ; ++pos) { if(pos>=uLength) break; // stop when we multiple a row by a column float m1 = texture2D(usampler,vec2(ss,r)).r; float m2 = texture2D(usampler,vec2(c,tt)).g; sum += (m1*m2); ss += uStepS; tt += uStepT; } return sum; } void main(void) { // get the implied row and column from .s and .t of passed texel float col = floor((vTex.s*uOutRows)); float row = floor((vTex.t*uOutCols)); // sum row x col for the passed pixel float v = sumrowcol(row,col); // Render to IEEE 754 Floating Point if (v==0.) { gl_FragColor = vec4(0.,0.,0.,0.); return; } float a = abs(v); // encode absolute value + sign float exp = floor(log2(a)); // number of powers of 2 float mant = (a * pow(2.,23.-exp)); // multiply to fill 24 bits (implied leading 1) float mant1 = floor(mant / 256. / 256.); // first 8 bits of mantissa float mant2 = mod(floor(mant / 256.),256.); // second 8 bits float mant3 = mod(mant,256.); // third 8 bits highp float sign = 128.-128.*(a/v); // sign bit is 256 or 0 highp float e = (sign+exp+127.)/510.; // exponent and sign highp float m1 = (mant1-(128.*(1.-mod(exp+127.,2.))))/255.; // handle leading bit highp float m2 = (mant2)/255.; // middle part highp float m3 = (mant3+.5)/255.; // scale to 0 - 255 gl_FragColor = vec4(m3,m2,m1,e); // output an IEEE754 32-bit floating point number }

Hit the test button to run. Typically, it'll take about 5 secs to multiply the larger matrices in Javascript.







