이 번역 페이지는 최신 내용을 담고 있지 않습니다. 최신 내용을 영문으로 보려면 여기를 클릭하십시오.
parfor
루프에서 변수 문제 해결하기
parfor
루프 변수는 연속으로 증가하는 정수여야 함
parfor
루프에서 루프 변수는 연속으로 증가하는 정수여야 합니다. 따라서 다음 예제는 오류를 반환합니다.
parfor i = 0:0.2:1 % not integers parfor j = 1:2:11 % not consecutive parfor k = 12:-1:1 % not increasing
iValues = 0:0.2:1; parfor idx = 1:numel(iValues) i = iValues(idx); ... end
parfor
루프에서 오버플로 방지하기
MATLAB®은 parfor
루프 변수의 오버플로 가능성을 감지하는 경우 오류를 보고합니다.
오버플로 조건 | 예제 | 해결책 |
---|---|---|
|
parfor idx=int8(-128:127) idx; end |
parfor idx=-128:127 int8(idx); end |
|
parfor idx=uint32(0:1) idx; end |
|
parfor
루프에서 변수 분류 문제 해결하기
MATLAB에서 parfor
루프에 있는 이름을 변수로 인식하면 변수는 다음 표에 있는 여러 범주 중 하나로 분류됩니다. 변수가 고유하게 분류되고 범주 요구 사항을 충족하는지 확인합니다. 요구 사항을 위반한 parfor
루프는 오류를 반환합니다.
분류 | 설명 |
---|---|
루프 변수 | 루프 인덱스 |
슬라이스 변수 | 서로 다른 루프의 반복에 의해 배열의 각 조각이 계산되는 배열 |
브로드캐스트 변수 | 내부에 값을 필요로 하지만 값이 할당되지 않은 루프 앞에 정의된 변수 |
Reduction Variables | 반복 순서에 관계없이 루프 반복을 통해 값을 누적하는 변수 |
임시 변수 | 루프 내에 생성되며 루프 외부에서 액세스되지 않는 변수 |
현재 어떤 변수가 있는지 알아보려면 코드 조각을 살펴보십시오. 위 표의 모든 변수 분류는 다음 코드로 표현됩니다.
변수 분류 문제에 봉착할 경우 parfor
루프의 본문을 함수로 변환하는 어려운 방법을 사용하기 전에 다음 방법을 고려해 보십시오.
중첩
for
루프를 사용하여 슬라이스 배열의 요소를 참조하는 경우parfor
루프 내 다른 곳에서는 이 배열을 사용할 수 없습니다. 왼쪽의 코드는A
가 중첩for
루프 내에서 나눠지고 요소 참조되기 때문에 작동하지 않습니다. 오른쪽의 코드는v
가 중첩 루프 바깥쪽에서A
에 할당되기 때문에 작동합니다. 전체 행을 계산한 다음 슬라이스 출력값에 한 번만 할당을 수행하면 됩니다.유효하지 않음 유효함 A = zeros(4, 10); parfor i = 1:4 for j = 1:10 A(i, j) = i + j; end disp(A(i, 1)) end
A = zeros(4, 10); parfor i = 1:4 v = zeros(1, 10); for j = 1:10 v(j) = i + j; end disp(v(1)) A(i, :) = v; end
왼쪽의 코드는
parfor
의 변수x
를 분류할 수 없기 때문에 작동하지 않습니다.x
의 각각의 다른 부분에 여러 번의 할당이 있으므로 이 변수는 분류할 수 없습니다. 따라서parfor
는 루프 반복 간에 종속성 유무를 확인할 수 없습니다. 오른쪽의 코드는x
의 값을 완전히 덮어쓰기 때문에 작동합니다. 이제parfor
는x
가 임시 변수임을 분명히 확인할 수 있습니다.유효하지 않음 유효함 parfor idx = 1:10 x(1) = 7; x(2) = 8; out(idx) = sum(x); end
parfor idx = 1:10 x = [7, 8]; out(idx) = sum(x); end
이 예제는 구조체형 배열의 필드를 나누는 방법을 보여줍니다. 자세한 내용은
struct
를 참조하십시오. 왼쪽의 코드는parfor
의 변수a
를 분류할 수 없기 때문에 작동하지 않습니다. 이 변수는 인덱싱 형식이 슬라이스 변수에 유효하지 않으므로 분류할 수 없습니다.a
의x
필드가 올바르게 나눠지는 것 같지만 첫 번째 수준의 인덱싱은 슬라이스 인덱싱 연산이 아닙니다. 오른쪽의 코드는struct
의 필드를 별도의 변수tmpx
로 추출하기 때문에 작동합니다. 이제parfor
는 이 변수가 나눠졌음을, 즉 슬라이스 변수임을 제대로 확인할 수 있습니다. 일반적으로struct
의 필드 또는 객체의 속성을parfor
의 슬라이스 입력 변수나 슬라이스 출력 변수로 사용할 수 없습니다.유효하지 않음 유효함 a.x = []; parfor idx = 1:10 a.x(idx) = 7; end
tmpx = []; parfor idx = 1:10 tmpx(idx) = 7; end a.x = tmpx;
parfor 루프에서 구조체형 배열
임시 구조체 만들기
parfor
루프에는 점 표기법 할당을 사용하여 구조체를 만들 수 없습니다. 왼쪽 코드에서 루프 내의 두 행은 분류 오류를 생성합니다. 오른쪽 코드에서는 우회적 해결 방법으로 struct
함수를 사용하여 루프 또는 첫 번째 필드에 구조체를 만들 수 있습니다.
유효하지 않음 | 유효함 |
---|---|
parfor i = 1:4 temp.myfield1 = rand(); temp.myfield2 = i; end | parfor i = 1:4 temp = struct(); temp.myfield1 = rand(); temp.myfield2 = i; end parfor i = 1:4 temp = struct('myfield1',rand(),'myfield2',i); end |
구조체 필드 나누기
parfor
루프에는 구조체 필드를 슬라이스 입력 또는 출력 배열로 사용할 수 없습니다. 즉, 루프 변수를 사용하여 구조체 필드의 요소를 참조할 수 없습니다. 왼쪽 코드에서 루프 내의 두 행은 인덱싱으로 인해 분류 오류를 생성합니다. 오른쪽 코드에서는 슬라이스 출력값에 대한 우회적 해결 방법으로 루프에 별도의 슬라이스 배열을 사용합니다. 그런 다음 루프가 완료된 후 구조체 필드를 할당합니다.
유효하지 않음 | 유효함 |
---|---|
parfor i = 1:4 outputData.outArray1(i) = 1/i; outputData.outArray2(i) = i^2; end | parfor i = 1:4 outArray1(i) = 1/i; outArray2(i) = i^2; end outputData = struct('outArray1',outArray1,'outArray2',outArray2); |
슬라이스 입력값에 대한 우회적 해결 방법은 구조체 필드를 루프 앞의 별도 배열에 할당하는 것입니다. 이 새 배열을 슬라이스 입력값으로 사용할 수 있습니다.
inArray1 = inputData.inArray1; inArray2 = inputData.inArray2; parfor i = 1:4 temp1 = inArray1(i); temp2 = inArray2(i); end
parfor
루프의 본문을 함수로 변환하기
다른 방법이 모두 실패할 경우 parfor
루프의 본문을 함수로 변환하면 parfor
루프의 변수 분류 문제를 대개 해결할 수 있습니다. 왼쪽 코드에서 코드 분석기는 변수 y의 문제에 플래그를 지정하지만 해결할 수 없습니다. 오른쪽 코드에서는 parfor
루프의 본문을 함수로 변환하여 이 문제를 해결합니다.
유효하지 않음 | 유효함 |
---|---|
function parfor_loop_body_bad data = rand(5,5); means = zeros(1,5); parfor i = 1:5 % Code Analyzer flags problem % with variable y below y.mean = mean(data(:,i)); means(i) = y.mean; end disp(means); end | function parfor_loop_body_good data = rand(5,5); means = zeros(1,5); parfor i = 1:5 % Call a function instead means(i) = computeMeans(data(:,i)); end disp(means); end % This function now contains the body % of the parfor-loop function means = computeMeans(data) y.mean = mean(data); means = y.mean; end Starting parallel pool (parpool) using the 'Processes' profile ... connected to 4 workers. 0.6786 0.5691 0.6742 0.6462 0.6307 |
모호하지 않은 변수 이름
MATLAB이 parfor
루프 내에서 변수로 분명하게 구별할 수 없는 이름을 사용하는 경우 MATLAB은 구문 분석 시 함수를 참조한다고 가정합니다. 그런 다음 런타임에 함수를 찾을 수 없으면 MATLAB은 오류를 생성합니다. 변수 이름 항목을 참조하십시오. 예를 들어, 다음 코드에서 f(5)
는 f
라는 배열의 5번째 요소를 의미하거나 인수가 5
인 f
라는 이름의 함수를 의미할 수 있습니다. f
가 코드에서 명확하게 변수로 정의되지 않은 경우 MATLAB은 코드가 실행될 때 경로에서 함수 f
를 검색합니다.
parfor i = 1:n ... a = f(5); ... end
투명 parfor
루프
parfor
루프의 본문은 투명해야 하는데, 이는 변수에 대한 모든 참조가 코드 텍스트에서 "볼 수 있어야" 한다는 것입니다. 투명성에 대한 자세한 내용은 parfor 루프 또는 spmd 문에서 투명성 확보하기 항목을 참조하십시오.
전역 변수 및 영속 변수
parfor
루프의 본문은 global
변수 선언이나 persistent
변수 선언을 포함할 수 없습니다.