2009-10-23 4 views
2

MATLAB에 대한 정말, 정말로 느린 프로그램을 작성하고 싶습니다. 나는 O (2^n) 또는 더 나쁜 것과 같이 말하고있다. 그것은 끝내야하고, 결정 론적으로 느려야합니다. 그래서 "만약 rand() = 123,123, exit!" 이것이 이상하게 들리지만 실제로는 분산 시스템 테스트 용입니다. .m 파일을 만들고 컴파일하고 (MCC), 디버깅 작업을 수행하기 위해 분산 시스템에서 실행해야합니다.의도적으로 느린 MATLAB 기능?

프로그램이 계속 작동해야하므로 sleep()은 유효한 옵션이 아닙니다.

무작위 대형 행렬을 만들고 그 역행렬을 찾으려고했지만 너무 빨리 완료되었습니다. 어떤 아이디어?

+1

확실히 단지 (당신의 매트릭스 반전처럼) 전혀 느린 무엇을하고 많은 여러 번합니까? – Peter

답변

4

이 분리 푸리에 변환의 구현은 1.86GHz 단일 코어 시스템에서 2048 개의 긴 입력 벡터 x에 대해 ~ 9 초가 걸립니다. 4096 입력으로 가면 O (N^2)에서 예상되는 4 배에 가까운 35 초까지 시간이 연장됩니다. 나는 더 이상 입력 : 시도하는 인내심이없는

function y = SlowDFT(x) 

t = cputime; 
y = zeros(size(x)); 
for c1=1:length(x) 
    for c2=1:length(x) 
     y(c1) = y(c1) + x(c2)*(cos((c1-1)*(c2-1)*2*pi/length(x)) - ... 
          1j*sin((c1-1)*(c2-1)*2*pi/length(x))); 
    end 
end 
disp(cputime-t); 

편집 : 또는 당신은 CPU보다 더 많은 메모리 스트레스를 찾고 있다면 :

function y = SlowDFT_MemLookup(x) 

t = cputime; 
y = zeros(size(x)); 
cosbuf = cos((0:1:(length(x)-1))*2*pi/length(x)); 
for c1=1:length(x) 
    cosctr = 1; 
    sinctr = round(3*length(x)/4)+1; 
    for c2=1:length(x) 
     y(c1) = y(c1) + x(c2)*(cosbuf(cosctr) ... 
          -1j*cosbuf(sinctr)); 
     cosctr = cosctr + (c1-1); 
     if cosctr > length(x), cosctr = cosctr - length(x); end 
     sinctr = sinctr + (c1-1); 
     if sinctr > length(x), sinctr = sinctr - length(x); end 
    end 
end 
disp(cputime-t); 

이 계산 죄보다 빠릅니다을 각 반복마다 cos. 2048 개의 긴 입력에는 3 초가 걸렸으며 16384 개의 긴 입력에는 180 초가 걸렸습니다.(심지어 아마도 복수의 반복에 대해)이 기준을 사용하여, 시험되는 다양한 세트의

:

tic 
isprime(primes(99999999)); 
toc 

EDIT :

1

당신은 적당하게 큰 X 어떻게 INV 사용에 대한

+0

적절히 큰 프라임'X '에 대한'factor (X)'는 더 느릴 수도 있고 그렇지 않을 수도 있습니다. –

+0

특정 속성을 갖는 큰 X의 경우 문제를 설정하는 데 최소한의 노력으로 많은 작업이 필요합니다. O (2^n) 일 가능성은 낮지 만 느린 것을 필요로합니다. –

+0

그리고 특정 속성을 가진 큰 X의 경우 쉽게 이해할 수 있습니다. 예를 들어 == 2^n 인 모든 X는 전혀 시간을 초월합니다. 이것이 내가 소수 또는 가짜 의사를 추천하는 이유입니다. Google에는 두 가지 목록이 있습니다. –

3

에 대한 factor(X)에게 질문을 할 수있어? 꽤 느린 reported되었습니다.

+0

나는 그것을 시도했다 ... 4 초 만에 1000x1000 행렬을 수행 할 수있다 ... –

+1

그런 다음 10000000x10000000 행렬을 시도한다. –

+0

@Vinko - Hehehe :) – Rook

2

저는 MATLAB을 말하지 않지만 다음과 같은 것이 효과가있을 수 있습니다.

loops = 0 
counter = 0 
while (loops < MAX_INT) { 
    counter = counter + 1; 
    if (counter == MAX_INT) { 
     loops = loops + 1; 
     counter = 0; 
    } 
} 

이렇게하면 MAX_INT * MAX_INT 회 반복됩니다. 이것이 충분하지 않다면 계산에 무거운 것을 루프에 넣을 수 있습니다.

+1

이것은 MATLAB의 루프가 느리고 악성 코드의 길이를 정확하게 제어 할 수 있기 때문에 특히 좋습니다. –

+0

@David : JIT 컴파일! – Jacob

+1

@David J : MATLAB이 루프를 가지고 느린 반면, 사실이라면 더 이상 그렇게 생각하지 않습니다. 몇 년 전에 추가 한 JIT가이를 변경했습니다. – MatlabDoug

2

일부 작업은 반복됩니다. 루프 반복 수를 사용하여 완료하는 데 걸리는 시간을 조정할 수 있습니다.

1

주어진 입력이 작은 숫자로 나누어서 소수인지 테스트 할 수도 있습니다. 이것은 당신에게 O (n^2)를 줄 것입니다.

+0

O (n)이 아니라 O (n^2). –

4

카운트 2 n. 선택적으로, 각 반복에서 느린 함수 호출을 만듭니다.

당신은 쉽게 설정할 메모리를 통해 CPU의 방식을 강조 실제 작업하려면
4

:

  • 대형 밀도 행렬 반전을 (충분히 느려지지가 큰 만들?.)
  • 요인을 RSA number
1

이것을 시도

disp(repmat('-',1,85)) 
disp(['MATLAB Version ' version]) 
disp(['Operating System: ' system_dependent('getos')]) 
disp(['Java VM Version: ' version('-java')]); 
disp(['Date: ' date]) 
disp(repmat('-',1,85)) 

N = 3000; % matrix size 
A = rand(N,N); 
A = A*A; 

tic; A*A; t=toc; 
fprintf('A*A \t\t\t%f sec\n', t) 

tic; [L,U,P] = lu(A); t=toc; clear L U P 
fprintf('LU(A)\t\t\t%f sec\n', t) 

tic; inv(A); t=toc; 
fprintf('INV(A)\t\t\t%f sec\n', t) 

tic; [U,S,V] = svd(A); t=toc; clear U S V 
fprintf('SVD(A)\t\t\t%f sec\n', t) 

tic; [Q,R,P] = qr(A); t=toc; clear Q R P 
fprintf('QR(A)\t\t\t%f sec\n', t) 

tic; [V,D] = eig(A); t=toc; clear V D 
fprintf('EIG(A)\t\t\t%f sec\n', t) 

tic; det(A); t=toc; 
fprintf('DET(A)\t\t\t%f sec\n', t) 

tic; rank(A); t=toc; 
fprintf('RANK(A)\t\t\t%f sec\n', t) 

tic; cond(A); t=toc; 
fprintf('COND(A)\t\t\t%f sec\n', t) 

tic; sqrtm(A); t=toc; 
fprintf('SQRTM(A)\t\t%f sec\n', t) 

tic; fft(A(:)); t=toc; 
fprintf('FFT\t\t\t%f sec\n', t) 

tic; isprime(primes(10^7)); t=toc; 
fprintf('Primes\t\t\t%f sec\n', t) 

다음은 N = 1000을 사용하는 내 컴퓨터의 결과입니다 하나의 반복만을위한 것입니다 (소수는 상한 10^7을 사용하지 않습니다 10^8 [시간이 더 걸립니다])

A*A    0.178329 sec 
LU(A)   0.118864 sec 
INV(A)   0.319275 sec 
SVD(A)   15.236875 sec 
QR(A)   0.841982 sec 
EIG(A)   3.967812 sec 
DET(A)   0.121882 sec 
RANK(A)   1.813042 sec 
COND(A)   1.809365 sec 
SQRTM(A)  22.750331 sec 
FFT    0.113233 sec 
Primes   27.080918 sec 
2

Easy! Turing machine의 뿌리로 돌아가서 O (2^n) 또는 더 나쁜 프로세스를 생각해보십시오.

다음은 아주 간단한 하나 (검증되지 않은 경고,하지만 당신은 요점을 파악)

N = 12; radix = 10; 
odometer = zeros(N, 1); 
done = false; 
while (~done) 
    done = true; 
    for i = 1:N 
     odometer(i) = odometer(i) + 1; 
     if (odometer(i) >= radix) 
      odometer(i) = 0; 
     else 
      done = false; 
      break; 
     end 
    end 
end 

더 좋은 방법을 반복적으로 피보나치 수를 계산하는 방법에 대한? fib (N)은 fib (N-1)과 fib (N-2)의 두 함수 호출을해야하지만 스택 깊이는 O (N)이므로 런타임은 O (2^N)입니다. 한 번에 일어난다.

function y = fib(n) 
    if (n <= 1) 
     y = 1; 
    else 
     y = fib(n-1) + fib(n-2); 
    end 
end 
+0

+와 *가 섞여 있습니다. 컨텍스트가 주어지면 그다지 중요하지 않습니다 ;-). –

+0

? 그 기능들 중 어느 것도 곱셈을 가져서는 안된다. 주행 거리계는 단지 증분이고 피보나치는 부가 적입니다. –

1

이 WANTED_TIME 초 100 %의 CPU를 실행합니다

WANTED_TIME = 2^n; % seconds 
t0=cputime; 
t=cputime; 
while (t-t0 < WANTED_TIME) 
    t=cputime; 
end; 
관련 문제