-5

I am trying to generate 5000 by 5000 random number matrix. Here is what I do with MATLAB:

for i = 1:100
    rand(5000)
end

And here is what I do in C++:

#include <iostream>
#include <stdlib.h>
#include <time.h>
#include <ctime>

using namespace std;


int main(){

    int N = 5000;
    double ** A = new double*[N];
    for (int i=0;i<N;i++)
        A[i] = new double[N];


    srand(time(NULL));

    clock_t start = clock();
    for (int k=0;k<100;k++){
        for (int i=0;i<N;i++){
            for (int j=0;j<N;j++){
                A[i][j] = rand();
            }
        }
    }

    cout << "T="<< (clock()-start)/(double)(CLOCKS_PER_SEC/1000)<< "ms " << endl;

}

MATLAB takes around 38 seconds while C++ takes around 90 seconds. In another question, people executed the same code and got same speeds for both C++ and MATLAB.

I am using visual C++ with the following optimizations https://i.stack.imgur.com/HXP8i.png

I would like to learn what I am missing here? Thank you for all the help.

EDIT: Here is the key thing though... Why MATLAB is faster than C++ in creating random numbers?

In this question, people gave me answers where their C++ speeds are same as MATLAB. When I use the same code I get way worse speeds and I am trying to understand why.

Community
  • 1
  • 1
  • 4
    These aren't equivalent. In the C++ case, you have a non-contiguous array, and each call to `rand` requires a subsequent conversion to `double`. At least try running with a contiguous array (i.e. `double *A = new double[5000*5000]`). – Oliver Charlesworth Aug 02 '15 at 14:00
  • Also it should read `CLOCKS_PER_SEC/1000.0`. `CLOCKS_PER_SEC` is defined as `(long)1000` on VS2015 but better stay on the safe side in case any other compiler/environment use different values. – Banex Aug 02 '15 at 14:07
  • 1
    Did you compile the c++ with optimizations switched on? – juanchopanza Aug 02 '15 at 14:11
  • 7
    This comparison is _completely_ meaningless. You know nothing about the differences between the `rand()` implementations, you have a gazillion dynamic allocations, you have next to no memory locality... Stop making such comparisons. If you're writing Matlab write Matlab. If you're writing C++ write C++. Then optimise your final product as/when/if required. Nothing more nothing less. – Lightness Races in Orbit Aug 02 '15 at 14:11
  • @LightnessRacesinOrbit: Actually, I'm no longer sure about locality. It appears that the OP's code is iterating in a cache-friendly order, and the dimensions are large enough such that the overhead due to non-contiguousness of successive rows should be negligible. I suspect the bulk of the difference is either due to Matlab secretly using multiple threads, or due to significant differences in how rand operates. – Oliver Charlesworth Aug 02 '15 at 14:14
  • @LightnessRacesinOrbit well my question is, why in the following link people are getting same speeds on both C++ and MATLAB using the same code? http://stackoverflow.com/questions/31692856/why-matlab-is-faster-than-c-in-creating-random-numbers – Serdar Oztetik Aug 02 '15 at 14:17
  • 2
    @radres: Wait, why do you have two essentially identical questions? – Oliver Charlesworth Aug 02 '15 at 14:18
  • @OliverCharlesworth In one of them I thought it was a problem about C++ and MATLAB. But when I see the answers I realized that I, personally, cannot reach the speeds the other people reach so I created another one. – Serdar Oztetik Aug 02 '15 at 14:20
  • Are you running the program without the debugger attached? Regardless of optimization. – Banex Aug 02 '15 at 14:20
  • @banex Yes I am compiling in release mod – Serdar Oztetik Aug 02 '15 at 14:31
  • @radres I'm not talking about compilation. Are you running the program through Debug --> Start Without Debugging? – Banex Aug 02 '15 at 14:35
  • @Banex Yes, I was building it in release mode and running it. But now that you said it, I tried your way and I still get the slow timing (1/3 speed of matlab) – Serdar Oztetik Aug 02 '15 at 14:43

4 Answers4

3

In your C++ code, you are doing 5000 allocations of double[5000] on the heap. You would probably get much better speed if you did a single allocation of a double[25000000], and then do your own arithmetic to convert your 2 indices to a single one.

Logicrat
  • 4,438
  • 16
  • 22
3

Your test is flawed, as others have noted, and does not even address the statement made by the title. You are comparing an inbuilt Matlab function to C++, not Matlab code itself, which in fact executes 100x more slowly than C++. Matlab is just a wrapper around the BLAS/LAPACK libraries in C/Fortran so one would expect a Matlab script, and a competently written C++ to be approximately equivalent, and indeed they are: This code in Matlab 2007b

tic; A = rand(5000); toc

executes in 810ms on my machine and this

#include <iostream>
#include <stdlib.h>
#include <time.h>
#include <ctime>

#define N 5000
int main()
{
    srand(time(NULL));

    clock_t start = clock();

    int num_rows = N,
        num_cols = N;
    double * A = new double[N*N];
    for (int i=0; i<N*N; ++i)
        A[i] = rand();

    std::cout << "T="<< (clock()-start)/(double)(CLOCKS_PER_SEC/1000)<< "ms " << std::endl;

    return 0;
}

executes in 830ms. A slight advantage for Matlab's in-house RNG over rand() is not too surprising. Note also the single indexing. This is how Matlab does it, internally. It then uses a clever indexing system (developed by others) to give you a matrix-like interface to the data.

Matt Phillips
  • 9,465
  • 8
  • 44
  • 75
  • same codes executes in 830 ms (c++) and the matlab one executes in 343 ms. I am trying to understand this big difference – Serdar Oztetik Aug 02 '15 at 14:26
  • 1
    @radres Are you using a more recent version of Matlab? I think more recent RNGs preserve more state between calls and are able to achieve greater efficiency. In this case the right C++ equivalent wouldn't be `rand()` but something from [std::random](http://www.cplusplus.com/reference/random/) – Matt Phillips Aug 02 '15 at 14:49
  • yes, mine is R2014b. Maybe that is the reason it is faster. – Serdar Oztetik Aug 02 '15 at 14:55
0

I believe MATLAB utilize multiple cpu cores on your machine. Have you try to write a multi-threaded version and measure the difference?

Also, the quality of (pseudo) random would also make slightly difference (but not that much).

Non-maskable Interrupt
  • 3,841
  • 1
  • 19
  • 26
  • I have tried using parallel_for it is of course way faster yet when I run either matlab or c++ they are both using only 1 core of the CPU. And again, there are other people using the same code and getting faster C++ speeds compared to mine. I do not understand what im doing wrong – Serdar Oztetik Aug 02 '15 at 14:10
  • Like other suggested, your memory layout is not contiguous, you also waste an indirect de-referencing on each double. That can significantly hurts performance and cause cache pollutions. – Non-maskable Interrupt Aug 02 '15 at 14:15
  • 2
    Matlab does not use multiple cores here. There is only one state for the random number stream which can be manipulated by only one thread at a time. – Daniel Aug 02 '15 at 14:19
0

In my experience,

  • First check that you execute your C++ code in release mode instead of in Debug mode. (Although I see in the picture you are in release mode)
  • Consider MPI parallelization.
  • Bear in mind that MATLAB is highly optimized and compiled with the Intel compiler which produces faster executables. You can also try more advanced compilers if you can afford them.
  • Last you can make a loop aggregation by using a function to generate combinations of i, j in a single loop. (In python this is a common practice given by the function product from the itertools library, see this)

I hope it helps.

Community
  • 1
  • 1
Santi Peñate-Vera
  • 1,053
  • 4
  • 33
  • 68