Imrik
Imrik

Reputation: 664

I need to do my operations faster

I have a piece of code that reads points from an stl, then I have to do a transformation, aplying a transformation matrix, of this stl and write the results on other stl. I do all this stuff, but it's too slow, about 5 or more minutes.

I put the code of the matrix multiplication, it recieves the two matrix and it makes the multiplication:

public double[,] MultiplyMatrix(double[,] A, double[,] B)
    {
        int rA = A.GetLength(0);
        int cA = A.GetLength(1);
        int rB = B.GetLength(0);
        int cB = B.GetLength(1);
        double temp = 0;
        double[,] kHasil = new double[rA, cB];
        if (cA != rB)
        {
            MessageBox.Show("matrix can't be multiplied !!");
        }
        else
        {
            for (int i = 0; i < rA; i++)
            {
                for (int j = 0; j < cB; j++)
                {
                    temp = 0;
                    for (int k = 0; k < cA; k++)
                    {
                        temp += A[i, k] * B[k, j];
                    }
                    kHasil[i, j] = temp;
                }
            }
            return kHasil;
        }
        return kHasil;
    }

My problem is that all the code is too slow, it has to read from a stl, multiply all the points and write in other stl the results, it spends 5-10 minutes to do that. I see that all comercial programs, like cloudcompare, do all this operations in a few seconds.

Can anyone tell me how I can do it faster? Is there any library to do that faster than my code?

Thank you! :)

Upvotes: 0

Views: 138

Answers (3)

Just for the records: CloudCompare is not a commercial product. It's a free open-source project. And there are no 'huge team of developers' (only a handful of them actually, doing this on their free time).

Here is our biggest secret: we use pure C++ code ;). And we rarely use multi-threading but for very lengthy processes (you have to take the thread management and processing time overhead into account).

Here are a few 'best practice' rules for the parts of the code that are called loads of times:

  • avoid any dynamic memory allocation
  • make as less (far) function calls as possible
  • always process the most probable case first in a 'if-then-else' branching
  • avoid very small loops (inline them if N = 2 or 3)

Upvotes: 0

pix
pix

Reputation: 1290

I fond this on internet:

 double[] iRowA = A[i];
double[] iRowC = C[i];
for (int k = 0; k < N; k++) {
    double[] kRowB = B[k];
    double ikA = iRowA[k];
    for (int j = 0; j < N; j++) {
        iRowC[j] += ikA * kRowB[j];
    }
}

then use Plinq

 var source = Enumerable.Range(0, N);
var pquery = from num in source.AsParallel()
             select num;
pquery.ForAll((e) => Popt(A, B, C, e));

Where Popt is our method name taking 3 jagged arrays (C = A * B) and the row to calculate (e). How fast is this:

 1.Name   Milliseconds2.Popt       187

Source is: Daniweb

That's over 12 times faster than our original code! With the magic of PLINQ we are creating 500 threads in this example and don't have to manage a single one of them, everything is handled for you.

Upvotes: 1

cyberj0g
cyberj0g

Reputation: 3787

You have couple of options:

  1. Rewrite your code with jagged arrays (like double[][] A) it should give ~2x increase in speed.

  2. Write unmanaged C/C++ DLL with matrix multiplication code.

  3. Use third-party math library that have native BLAS implementation under the hood. I suggest Math.NET Numerics, it can be switched to use Intel MKL which is smoking fast.

Probably, the third option is the best.

Upvotes: 0

Related Questions