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 변수 선언을 포함할 수 없습니다.