3

나는 지난주에 다시 작성하여 가능한 한 빨리 실행하도록 코드를 작성했습니다.대용량 모델 최적화 - 병렬 처리를 시도하는 중

코드는 회절 레이저 빔을 모델링하며 그 본질은 많은 2D 1280 * 1280 슬라이스에 걸쳐 640 * 640 커널의 컨볼 루션입니다. 각 슬라이스는 빔 축을 따라 새 위치가됩니다.

최적화 단계는 내 기능을 컴파일하는 것이었고 두 번째 단계는 Mathematica가 큰 데이터 목록으로 작업하는 것을 좋아한다는 것을 배우고 있었기 때문에 여러 레이어의 3D 공간을 순차적으로 슬라이스가 아닌 한 번에 전달했습니다.

그러나 이것은 내 RAM을 먹었습니다! 여기

내 전류 설정 :

Func2[K_ , ZRange_] := 
Module[{layers = Dimensions[ZRange][[1]]}, 
x = ConstantArray[Table[x, {x, -80, 80, 0.125}, {y, -80, 80, 0.125}], {layers}]; 
y = ConstantArray[Table[y, {x, -80, 80, 0.125}, {y, -80, 80, 0.125}], {layers}]; 
z = Table[ConstantArray[z, {1281, 1281}], {z, ZRange}]; 

UTC = Func3[x, y, z]; 

Abs[ListConvolve[K, #] & /@ UTC] 
] 


Func3 = Compile[{{x, _Real}, {y, _Real}, {z, _Real}}, 
Module[{Sr2R2 = Sqrt[x^2 + y^2 + z^2]}, 
0.5 (1. + z/Sr2R2) Exp[2 \[Pi] I (Sr2R2 - z)]/Sr2R2], 
RuntimeAttributes -> {Listable}, 
CompilationTarget -> "C" 
]; 


ZRangeList = {{20., 19., 18., 17., 16., 15., 14., 13., 12., 11.}, 
       {10., 9., 8., 7., 6., 5., 4., 3., 2., 1.}}; 


results = Table[Func2[kernel, ZList], {ZList, ZRangeList}]; 

일부 설명 : 나는 가능한 한 많이 컴파일 할 수 있도록 원하는대로

  • 작품은 두 가지 기능으로 분할됩니다.
  • Z 값은 함수의 여러 레이어를 한 번에 평가할 수 있도록 목록으로 나뉩니다.

몇 가지 질문 :

  • 방법이 더 빨리 만들 것?
  • 실행하면, 두 개의 코어가 사용되지만 하나의 mathematica 커널이 사용됩니다. ParallelTable로 실행할 경우 여러 커널을 실행하지만 더 많은 RAM을 먹고 궁극적으로 느립니다.
  • 가능한 한 많은 코어에서 실행할 수 있기를 원합니다. LightweightGrid가 실행 중입니다. 어떻게 할 수 있습니까?
  • 다른 차원의 컴파일 된 함수 목록을 전달할 수없는 이유는 무엇입니까? 나 즉시 밖으로 점프

답변

1

것입니다

복근 [ListConvolve [K #] &/@ UTC] ListConvolve [K #] &, UTC @ parallelMap은 [복근으로 만들어 질 수 ]

그러나 ParallelTable이 일반 테이블보다 느리다는 사실은 놀랍습니다. 그 이유는 2 가지 상황에서만 ParallelTable이 느리다는 것입니다. 즉, 병렬 처리가 병렬 처리보다 병렬 처리에 비해 비용이 많이 들기 때문에 서브 커널 사이에 너무 많은 통신이 필요합니다.

병렬 처리 할 때 정의를 배포 했습니까? 예 : 위의 경우, 시작하기 전에 LaunchKernels을 먼저 시작한 다음 K의 정의를 배포합니다 (UTC는 배포 할 필요가 없습니다. 서브 커널에서 실제로 사용되지 않기 때문에 UTC는 배포하지 않아도됩니다.) 뿐만 아니라 공유 []의 사용은 메모리 부하를 줄일 수 있습니다.

는 CUDA와 함께이 일을 생각 했습니까? 당신이 함수 내부에서하고있는 단순한 숫자 수학에 대한 완벽한 보인다.

는 또한 통지, 당신에게 ' 테이블 [x, {x, -80, 80, 0.125}, {y, -80, 80, 0.125}]을 항상 변수로 만들고 변수의 값을 ConstantArray로 만드는 이유는 무엇입니까? 그 변수? 당신은 그 중 하나에 대해 약 0.2 초를 낭비하고 있습니다.

마지막으로, 작은 작은 특질 : - : (확인 주시기

Module[{Sr2R2 = Sqrt[x^2 + y^2 + z^2]}, 
     0.5 (1. + z/Sr2R2) Exp[2 \[Pi] I (Sr2R2 - z)]/Sr2R2] 

더 나은로 머리를 만들 수 있습니다 부문은 항상 최적화하려고 할 때 할 수있는 끔찍한 일이 많은 시간이 소요입니다 내 수학) :

Module[{R2=N[x^2 + y^2 + z^2],Sr2R2 = Sqrt[R2]}, 
     (0.5 Exp[2 I \[Pi] (Sr2R2 - z)] (Sr2R2 + z))/R2] 
1

어느 병렬화이나 심지어 C 컴파일 (GCC 4.7을 사용하여 equation.com에서 윈도우 64 비트)에 VC++ Express에서 증강은 타이밍을 개선한다.

이 코드는 약 6.5 초해야 실행 : 때 ParallelTable 알아 내기 위해

$start = AbsoluteTime[]; 
CFunc2 = Compile[{{kern, _Real, 2}, {ZRange, _Real, 1}}, 
    Module[{layers = Length[ZRange], x, y, z, UTC, ty, Sr2R2}, 
    ty = Table[y, {x, -80, 80, 0.125}, {y, -80, 80, 0.125}]; 
     x = Table[x, {layers}, {x, -80, 80, 0.125}, {y, -80, 80, 0.125}]; 
     y = Table[y, {layers}, {x, -80, 80, 0.125}, {y, -80, 80, 0.125}]; 
     z = Table[ConstantArray[z, {1281, 1281}], {z, ZRange}]; 
     Sr2R2 = Sqrt[x^2 + y^2 + z^2]; UTC = 0.5*(1. + z/Sr2R2)* 
     (Exp[2*Pi*I*(Sr2R2 - z)]/Sr2R2); 
     Abs[(ListConvolve[kern, #1] &) /@ UTC]]]; 
ZRangeList = {{20., 19., 18., 17., 16., 15., 14., 13., 12., 11.}, 
    {10., 9., 8., 7., 6., 5., 4., 3., 2., 1.}}; 
SeedRandom[1]; kernel = RandomReal[{-1, 1}, {640, 640}]; 
results = Table[CFunc2[kernel, ZList], {ZList, ZRangeList}]; 
AbsoluteTime[] - $start 

그것은 일반적으로 너무 쉽게되지 않습니다 :

$start = AbsoluteTime[]; 
Func2[K_, ZRange_] := 
Module[{layers = Dimensions[ZRange][[1]], x, y, z, UTC, tx, ty, t1}, 
    tx = Table[x, {x, -80, 80, 0.125}, {y, -80, 80, 0.125}]; 
    ty = Table[y, {x, -80, 80, 0.125}, {y, -80, 80, 0.125}]; 
    x = ConstantArray[tx, {layers}]; 
    y = ConstantArray[ty, {layers}]; 
    z = Table[ConstantArray[z, {1281, 1281}], {z, ZRange}]; 
    t1 = AbsoluteTime[]; 
    UTC = Func3[x, y, z]; 
    Print["Func3 time = ", AbsoluteTime[] - t1]; 
    Abs[ListConvolve[K, #] & /@ UTC]] 
Func3 = Compile[{{x, _Real, 3}, {y, _Real, 3}, {z, _Real, 3}}, 
    Module[{Sr2R2 = Sqrt[x^2 + y^2 + z^2]}, 
    0.5 (1. + z/Sr2R2) Exp[2 \[Pi] I (Sr2R2 - z)]/Sr2R2]]; 
ZRangeList = {{20., 19., 18., 17., 16., 15., 14., 13., 12., 
    11.}, {10., 9., 8., 7., 6., 5., 4., 3., 2., 1.}}; 
SeedRandom[1]; kernel = RandomReal[{-1, 1}, {640, 640}]; 
results1 = Table[Func2[kernel, ZList], {ZList, ZRangeList}]; 
AbsoluteTime[] - $start 

하나 개의 함수로 모든 것을 컴파일하는 것은 느린 (8.1 초) 친구들이 정말로 도움이됩니다. 문제, 크기, Mathematica verison 등에 따라 달라집니다.

관련 문제