필터 지우기
필터 지우기

Loop unrolling question

조회 수: 3 (최근 30일)
David
David 2011년 9월 2일
Hi, I'm trying to generate the matrix A usually used for least-square fitting, namely columns of sine and cosine of increasing frequency. The number of desired frequencies (columns) is passed as a parameter. I'm trying to figure out a 'non-for-loop' way to generate the matrix. I managed to vectorize the column length using the time vector, but I can't find how to vectorize the number of columns!
For example,
Given: npoints = 1024; w = 1; fs = 55000 t = 0:(1/fs):((npoints-1)/fs);
Now if ncolumns=1, we want: A=[ones(npoints,1) cos(t'*w/fs) sin(t'*w/fs)];
Now if ncolumns=2, we want A=[ones(npoints,1) cos(t'*w/fs) sin(t'*w/fs) cos(2*t'*w/fs) sin(2*t'*w/fs)];
Now if ncolumns=3, we want A=[ones(npoints,1) cos(t'*w/fs) sin(t'*w/fs) cos(2*t'*w/fs) sin(2*t'*w/fs) cos(3*t'*w/fs) sin(3*t'*w/fs)];
Is there a nice way to do this without a for loop or a bunch of 'if'?
Thanks! David

답변 (5개)

Andrei Bobrov
Andrei Bobrov 2011년 9월 2일
variant
npoints = 1024;
w = 1;
fs = 55000;
t = (0:npoints-1)'/fs;
p1 = t*w/fs*(1:ncls);
A = [ones(npoints,1) reshape(permute(cat(3,sin(p1),cos(p1)),[1 3 2]),npoints,[])];
variant 2
npoints = 1024;
w = 1;
fs = 55000;
t = (0:npoints-1)'/fs;
p1 = t*w/fs*(1:ncls);
data = sortrows([1:2:2*ncls,2:2:2*ncls;cos(p1),sin(p1)]')';
A = [ones(npoints,1) data(2:end,:)];
variant 3
p = (0:npoints-1)'/fs*w/fs;
for i1 = ncls:-1:1
ii = i1*2;
ang = i1*p;
A1(:,ii+1) = sin(ang);
A1(:,ii) = cos(ang);
end
A1(:,1) = ones(npoints,1);
comparing the run-time of variants 1 and 3
>> t1=zeros(20,2);
npoints = 1024;
w = 1;
fs = 1;
ncls =1500;
for j1 = 1:20
%variant 3 loop
tic,
p = (0:npoints-1)'/fs*w/fs;
for i1 = ncls:-1:1
ii = i1*2;
ang = p*i1;
A1(:,ii+1) = sin(ang);
A1(:,ii) = cos(ang);
end
A1(:,1) = ones(npoints,1);
t1(j1,1) = toc;clear p A1
%variant 1 vectorized
tic
p1 = (0:npoints-1)'/fs*w/fs*(1:ncls);
A2 = [ones(npoints,1) reshape(permute(cat(3,cos(p1),sin(p1)),[1 3 2]),npoints,[])];
t1(j1,2) = toc;clear p1 A2
end
runtime = [min(t1);mean(t1);max(t1)];
>> runtime
runtime =
0.1639 0.1510
0.1720 0.1720
0.1868 0.2067
  댓글 수: 4
Andrei Bobrov
Andrei Bobrov 2011년 9월 2일
more add 'variant 2'
Andrei Bobrov
Andrei Bobrov 2011년 9월 3일
more add 'variant 3' and comparing the run-time

댓글을 달려면 로그인하십시오.


David
David 2011년 9월 2일
Hi, Now both variants and the for loop work great. However, I tried calculating the time taken to create the matrix for large value of [t] and ncls using tic/toc. Turned out the for loop was substantially much faster (about 3x)! I'm now confused with loop unrolling!

Derek O'Connor
Derek O'Connor 2011년 9월 2일
David,
What you call loop unrolling is not. Here is a rolled-up loop:
for i = 1:n
a(i) = b(i)*c(i)
end
Here is the same loop unrolled with a stride of 3:
for i = 1:3:n
a(i) = b(i)*c(i);
a(i+1) = b(i+1)*c(i+1);
a(i+2) = b(i+2)*c(i+2);
end
Loop unrolling may speed up the loop because there are now n/3 rather than n loop control tests. Optimizing compilers may automatically do loop unrolling, even when you don't want it.
I suspect you are interested in vectorization rather than loop unrolling.
Your latest comment suggests you have discovered some of the "joys" of vectorization.

David
David 2011년 9월 3일
Hi Derek, I understand what you're saying. I meant vectorization.
But I guess my question still holds. One of the first thing than any Matlab manual says is to use vectorization as much as possible to speed up the program. Doesn't seem to be the case here...
Thanks, David

Derek O'Connor
Derek O'Connor 2011년 9월 4일
Most of those manuals or books are out of date, or are unaware of the JIT compiler, or do not understand what the JIT compiler does (who does?).
Vectorization is not always a good thing. I have many examples where it both slows down the code and increases the memory.
My advice is to first write your program in the simplest possibe way, using loops. Time it. Vectorize and time it. Compare.
Here is a "tip from the horse's mouth", by Matlab's Doug Hull:
"I have seen some tortured logic in the name of vectorizing code. These cases could easily be replaced with a clear, readable for loop. The coder gained nothing in speed with this, yet lost readability.
Vectorizing is the right thing to do in many cases, taking advantage of MATLAB's matrix centric view of the world. It is not always the right thing though. Since the JIT (Just In Time) compiler was introduced, the former 'for loop penalty' is largely gone. Vectorizing is not always important for speed now."

카테고리

Help CenterFile Exchange에서 Loops and Conditional Statements에 대해 자세히 알아보기

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by