MATLAB: Faster pre-allocation of zeros-matrix [duplicate] - matlab

This question already has answers here:
Faster way to initialize arrays via empty matrix multiplication? (Matlab)
(4 answers)
Closed 9 years ago.
/edit: See here for an interesting discussion of the topic. Thanks #Dan
Using a(m,n) = 0 appears to be faster, depending of the size of matrix a, than a = zeros(m,n). Are both variants the same when it comes to pre-allocation before a loop?

They are definately not the same.
Though there are ways to beat the performance of a=zeros(m,n), simply doing a(m,n) = 0 is not a safe way to do it. If any entries in a already exist they will keep existing.
See this for some nice options, also consider doing the loop backwards if you don't mind the risk.

I think it depends on your m and n. You can check the time for yourself
tic; b(2000,2000) = 0; toc;
Elapsed time is 0.004719 seconds.
tic; a = zeros(2000,2000); toc;
Elapsed time is 0.004399 seconds.
tic; a = zeros(2,2); toc;
Elapsed time is 0.000030 seconds.
tic; b(2,2) = 0; toc;
Elapsed time is 0.000023 seconds.

Related

why Matlab parfeval function slower than normal? [duplicate]

This question already has an answer here:
Why is this simple parallel Matlab program much slower than the non-parallel version?
(1 answer)
Closed 12 months ago.
When I call function normally, execution time is much faster than parfeval.
tic
f = parfeval(#magic,1,10000);
value = fetchOutputs(f);
toc
Elapsed time is 2.244390 seconds.
magic function works on parfeval with 2.24 seconds.
tic
magic(10000);
toc
Elapsed time is 0.592743 seconds.
But when i call normally, it works fastly. What is the reason of this and How to speed up parfeval function?
In general, there is some overhead that needs to be considered when setting up threads (which parfeval does). This is the main reason for the time discrepancy.
When using any kind of parallel processing you have to first determine if the process runs long enough that the overhead from spawning the processes is negligible. In this case, it isn't.
Testing a longer run case:
tic
test(1E10)
toc
tic
f = parfeval(#test, 1, 1E10)
value = fetchOutputs(f);
toc
function x = test(n)
x = 1;
for i = 1:n
x = x * 1;
end
end
Which gives the time (on my computer) 5.51 and 5.49 seconds.

Multiple Tesla K80 GPU's and parfor loops

I received a computer with 4xGPU's Tesla K80 and I am trying the parfor loops from Matlab PCT to speed up FFT's calculation and it is yet slower.
Here is what I am trying:
% Pupil is based on a 512x512 array
parfor zz = 1:4
gd = gpuDevice;
d{zz} = gd.Index;
probe{zz} = gpuArray(pupil);
Essai{zz} = gpuArray(pupil);
end
tic;
parfor ii = 1:4
gd2 = gpuDevice;
d2{ii} = gd2.Index;
for i = 1:100
[Essai{ii}] = fftn(probe{ii});
end
end
toc
%%
Starting parallel pool (parpool) using the 'local' profile ... connected to 4 workers.
Elapsed time is 1.805763 seconds.
Elapsed time is 1.412928 seconds.
Elapsed time is 1.409559 seconds.
Starting parallel pool (parpool) using the 'local' profile ... connected to 8 workers.
Elapsed time is 0.606602 seconds.
Elapsed time is 0.297850 seconds.
Elapsed time is 0.294365 seconds.
%%
tic; for i = 1:400; Essai{1} = fftn( probe{1} ); end; toc
Elapsed time is 0.193579 seconds !!!
Why is opening 8 workers faster as in principle I stored my variables into 4gpu's only (out of 8)?
Also, how to use a Tesla K80 as a single GPU?
Merci, Nicolas
I doubt that parfor works for multi-GPU systems. If speed is critical and you want to take full advantage of your GPUs, I suggest to write your own little CUDA script using the cuFFT library:
http://docs.nvidia.com/cuda/cufft/#multiple-GPU-cufft-transforms
Here is how to write your mex file containing CUDA code:
http://www.mathworks.com/help/distcomp/run-mex-functions-containing-cuda-code.html
many thanks for your quick reply and for the links ! It is true that I was trying to avoid CUDA but it seems like the best option to spread FFTs.
Although I thought that parfor and spmd were great tools for multiple GPUs..

Save/load a large matrix in Octave

I'm playing with large pointcloud data in Octave (different files ranging from [10^5 to 10^7, 4] elements) and I'm looking for ways to optimize the code.
Right now I am trying to save the data into a .mat file as I've read somewhere (confirmation needed) that loading from a .mat file is much faster than loading the actual data.txt file every time.
save -ascii myfile data works fine needs since it's only numerical values I want to store but
load('myfile.mat') brings up a 1x1 matrix containing all the values instead of having a nx4 matrix, which is strange because when I use load('data.txt') I get a full nx4 matrix.
The problem seems to be with the save syntax. Any way I can save the file so I can load it with its original dimensions? Or do I have to manipulate the resulting 1x1 variable somehow?
Bonus question:
Browsing through some answers I kinda got the feeling that working with the transpose matrix instead of the nx4 would improve runtime considerably. Is that true?
Use a binary format if speed matters. Below a little speed comparison
a = rand (1e6, 4);
fn = tmpnam;
tic; save ("-ascii", fn, "a"); toc;
tic; load ("-ascii", fn); toc;
stat (fn).size
tic; save ("-v7", fn, "a"); toc;
tic; load ("-v7", fn); toc;
stat (fn).size
tic; save ("-v6", fn, "a"); toc;
tic; load ("-v6", fn); toc;
stat (fn).size
tic; save ("-binary", fn, "a"); toc;
tic; load ("-binary", fn); toc;
stat (fn).size
which gives
Elapsed time is 2.82237 seconds.
Elapsed time is 6.28686 seconds.
ans = 61000000
Elapsed time is 1.54074 seconds.
Elapsed time is 0.252718 seconds.
ans = 30192558
Elapsed time is 0.030833 seconds.
Elapsed time is 0.047183 seconds.
ans = 32000184
Elapsed time is 0.116342 seconds.
Elapsed time is 0.0523431 seconds.
ans = 32000045
As you can see -v6 is much faster than -ascii
EDIT: also keep in mind that "-ascii" only uses single precision floats

Is there any way to use hashtables/hashmaps in matlab? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Hash tables in MATLAB
General Question
Is there any way to get a hashset or hashmap structure in Matlab?
I often find myself in situations where I need to find unique entries or check membership in vectors and using commands like unique() or logical indexing seems to search through the vectors and is really slow for large sets of values. What is the best way to do this in Matlab?
Example
Say, for example, that I have a list of primes and want to check if 3 is prime:
primes = [2,3,5,7,11,13];
if primes(primes==3)
disp('yes!')
else
disp('no!')
end
if I do this with long vectors and many times things get really slow.
In other languages
So basically, is there any equivalents to python's set() and dict(), or similarly Java's java.util.HashSet and java.util.HashMap, in Matlab? And if not, is there any good way of doing lookups in large vectors?
Edit: reflection on the answers
This is the running time i got on the suggestions in the answers.
>> b = 1:1000000;
>> tic; for i=1:100000, any(b==i);; end; toc
Elapsed time is 125.925922 seconds.
s = java.util.HashSet();
>> for i=1:1000000, s.add(i); end
>> tic; for i=1:100000, s.contains(i); end; toc
Elapsed time is 25.618276 seconds.
>> m = containers.Map(1:1000000,ones(1,1000000));
>> tic; for i=1:100000, m(i); end; toc
Elapsed time is 2.715635 seconds
The construction of the java set was quite slow as well though so depending on the problem this might be quite slow as well. Really glad about the containers.Map tip. It really destroys the other examples, and it was instant in set up too.
Like this?
>> m = java.util.HashMap;
>> m.put(1,'hello,world');
>> m.get(1)
ans =
hello, world
Alternatively, if you want a Matlab-native implementation, try
>> m = containers.Map;
>> m('one') = 1;
>> m('one')
ans =
1
This is actually typed - the only keys it will accept are those of type char. You can specify the key and value type when you create the map:
>> m = containers.Map('KeyType','int32','ValueType','double');
>> m(1) = 3.14;
>> m(1)
ans =
3.14
You will now get errors if you try to put any key other than an int32 and any value other than a double.
You also have Sets available to you:
>> s = java.util.HashSet;
>> s.put(1);
>> s.contains(1)
ans =
1
>> s.contains(2)
ans =
0
Depending on how literal your example is, the disp will be a massive overhead (I/O is very slow).
That aside, I believe the quickest way to do a check like this is:
if find(primes==3,1,'first')
disp('yes');
else
disp('no');
end
Edit, you could also use any(primes==3) - a quick speed test shows they're approximately equivalent:
>> biglist = 1:100000;
>> tic;for i=1:10000
find(biglist==i,1,'first');
end
toc
Elapsed time is 1.055928 seconds.
>> tic;for i=1:10000
any(biglist==i);
end
toc
Elapsed time is 1.054392 seconds.

Several time counters in MATLAB

I have a program running a loop I want to have two time counters, one for the loop, that will tell me how log did one iteration of the loop took, and one for the entire program. To the best of my knowledge tic and toc will work only once.
You're only familiar with this tic toc syntax:
tic; someCode; elapsed = toc;
But there is another syntax:
start = tic; someCode; elapsed = toc(start);
The second syntax makes the same time measurement, but allows you the option of running more than one stopwatch timer concurrently. You assign the output of tic to a variable tStart and then use that same variable when calling toc. MATLAB measures the time elapsed between the tic and its related toc command and displays the time elapsed in seconds. This syntax enables you to time multiple concurrent operations, including the timing of nested operations (matlab documentation of tic toc).
Here's how to use it in your case. Let's say that this is your code:
for i = 1:M
someCode;
end
Insert the tic and toc like this:
startLoop = tic;
for i = 1:N
startIteration = tic;
someCode;
endIteration = toc(startIteration);
end
endLoop = toc(startLoop);
You can also use the above syntax to create a vector for which the ith element is the time measurement for the ith iteration. Like this:
startLoop = tic;
for i = 1:N
startIteration(i) = tic;
someCode;
endIteration(i) = toc(startIteration(i));
end
endLoop = toc(startLoop);
You can use tic and toc to time nested operations, from the Matlab help for tic:
tStart=tic; any_statements; toc(tStart); makes the same time measurement, but allows you the option of running more than one stopwatch timer concurrently. You assign the output of tic to a variable tStart and then use that same variable when calling toc. MATLAB measures the time elapsed between the tic and its related toc command and displays the time elapsed in seconds. This syntax enables you to time multiple concurrent operations, including the timing of nested operations
I'm not able to try this right now, but you should be able to use multiple tic and toc statements if you store the tic values into variables.
Read Matlab's documentation on this, there is even a section on nesting them. Here is a rough example:
tStartOverall = tic;
...
tStartLoop = tic;
<your loop code here>
tEndLoop = toc(tStartLoop);
...
tEndOverall = toc(tStartOverall);