มาลองทำให้โค้ดMathematicaรันเร็วขึ้น

โค้ดที่เขียนด้วยMathematicaหรือภาษา Wolfram นั้นมันจะมีวิธีที่ช่วยให้มันรันได้เร็วขึ้นอยู่หลายวิธีครับ ขึ้นกับปัญหาและวิธีการเขียน ที่จะโชว์ให้ดูนี้ผมก็ใช้เทคนิคง่ายๆด้วยการทำ parallel ด้วยคำสั่ง ParallelTable และ compile ด้วยคำสั่ง Compile ครับ  โค้ดตัวอย่างที่จะเอามาลองนี้เป็นโค้ดที่ใช้วาดรูป Mandelbrot set ครับ

แบบที่ 1 เป็นโค้ดเริ่มต้นที่ยังไม่มีการทำให้มันเร็วครับเขียนโดยใช้ loop จากคำสั่ง Table

AbsoluteTiming[
 test1 = Block[{i, x, p}, 
    Table[i = 0; x = 0. I; p = r + I c; 
     While[Abs@x <= Sqrt[2] && i < 9^3, x = x^2 + p; ++i]; 
     Tanh[Power[i/9^3, (7)^-1]], {c, -1, 1, .01}, {r, -2, 1, .01}]];]

(* เวลาที่ใช้คือ 77.4437 วินาที *)

แบบที่ 2 ในแบบนี้ผมทดลองให้มันรันแบบขนานโดยใช้คำสั่ง ParallelTable เครื่องที่ผมใช้นี้มันมี 4 cores ครับ เวลาก็ลดลง ถ้าคิดง่ายๆก็ใช้เวลาเหลือเกือบๆ 1 ใน 4

AbsoluteTiming[
 test2 = Block[{i, x, p}, 
    ParallelTable[i = 0; x = 0. I; p = r + I c; 
     While[Abs@x <= Sqrt[2] && i < 9^3, x = x^2 + p; ++i]; 
     Tanh[Power[i/9^3, (7)^-1]], {c, -1, 1, .01}, {r, -2, 1, .01}]];]

(* เวลาที่ใช้คือ 23.8938 วินาที *)

แบบที่ 3  แบบนี้ก็คือเอาแบบที่ 1 มา compile เป็น binary code ด้วยคำสั่ง Compile เวลาก็เร็วขึ้นอย่างเห็นได้ชัด

test3 = Compile[{}, 
  Block[{i, x, p}, 
   Table[i = 0; x = 0. I; p = r + I c; 
    While[Abs@x <= Sqrt[2] && i < 9^3, x = x^2 + p; ++i]; 
    Tanh[Power[i/9^3, (7)^-1]], {c, -1, 1, .01}, {r, -2, 1, .01}]]]

AbsoluteTiming[test3[];]

(* เวลาที่ใช้คือ 2.68316 วินาที *)

แบบที่ 4  แบบนี้ก็คือแบบที่ 3 ที่เอามารันแบบขนานด้วยคำสั่ง ParallelTable ซึ่งเวลาที่ใช้ก็เร็วขึ้นอีกกว่าแบบที่ 3

test4 = Compile[{{c, _Real}, {r, _Real}},
   Module[{i, x, p},
    i = 0; x = 0. I; p = r + I c; 
    While[Abs@x <= Sqrt[2] && i < 9^3, x = x^2 + p; ++i]; 
    Tanh[Power[i/9^3, (7)^-1]]
    ]
   ];

ParallelTable[
   test4[c, r], {c, -1, 1, .01}, {r, -2, 1, .01}]; // AbsoluteTiming

(* เวลาที่ใช้คือ 1.04455 วินาที *)

แบบที่ 5 แบบนี้เหมือนกับแบบที่ 4 แต่แทนที่จะให้มัน compile เป็น binary code โดย Mathematica เอง ก็ให้มันแปลงเป็นภาษา C ด้วย option CompilationTarget -> “C” เลยโดยใช้ compiler อย่าง gcc ครับ เวลาก็เร็วขึ้นอีกประมาณ 60% จากแบบที่ 4 ครับ

Needs["CCompilerDriver`GenericCCompiler`"]

$CCompiler = {"Compiler" -> GenericCCompiler, 
   "CompilerInstallation" -> "C:/Rtools/mingw_64", 
   "CompilerName" -> "x86_64-w64-mingw32-gcc.exe"};


test5 = Compile[{{c, _Real}, {r, _Real}},
   Module[{i, x, p},
    i = 0; x = 0. I; p = r + I c; 
    While[Abs@x <= Sqrt[2] && i < 9^3, x = x^2 + p; ++i]; 
    Tanh[Power[i/9^3, (7)^-1]]
    ], CompilationTarget -> "C"];

ParallelTable[
   test5[c, r], {c, -1, 1, .01}, {r, -2, 1, .01}]; // AbsoluteTiming

(* เวลาที่ใช้ 0.393584 วินาที *)

 

%d bloggers like this: