2016-12-03 37 views
3

我对C#相当陌生,我需要一些帮助来优化我的代码。针对执行速度优化双循环

struct Data 
{ 
    public static int numberOfPixels; 
    public static string[] filePaths; 
    public static string[] fileNames; 
    public static double[] z; 
    public static int numberOfFrames; 
    public static byte[][] imageBuffer; 
    public static int bufferSize = 1000; 
    public static double[] num; 
    public static double[] den; 
} 
public class Methods 
{ 
    public void RetrieveFileList() 
    { 
     Console.WriteLine("Please enter the folder path where all measurement files are stored: "); 
     Data.filePaths = Directory.GetFiles(Console.ReadLine(),"*.bin"); 
     Data.fileNames = new string[Data.filePaths.Length]; 
     Data.numberOfFrames = Data.filePaths.Length; 
     Data.z = new double[Data.filePaths.Length]; 
     int n = 0; 
     foreach(string file in Data.filePaths) 
     { 
      Data.fileNames[n] = Path.GetFileNameWithoutExtension(file); 
      n++; 
     } 
    } 
    public void CreatePositionArray() 
    { 
     Console.WriteLine("Please enter the stepsize used during the scan in nanometers: "); 
     double stepsize = Convert.ToDouble(Console.ReadLine()); 
     int n = 0; 
     foreach(string file in Data.fileNames) 
     { 
      Data.z[n] = Convert.ToInt32(file) * stepsize/1000; 
      n++; 
     } 
    } 
    public void InitializeBufferArray() 
    { 
     Data.imageBuffer = new byte[Data.numberOfFrames][]; 
    } 
    public byte[] ReadBinaryFile(int index) 
    { 
     return File.ReadAllBytes(Data.filePaths[index]); ; 
    } 
    public void FillImageBuffer() 
    { 
     for (int i = 0; i < Data.bufferSize; i++) 
     { 
      Data.imageBuffer[i] = ReadBinaryFile(i); 
     } 
     Data.numberOfPixels = Data.imageBuffer[0].Length; 
     Data.num = new double[Data.numberOfPixels]; 
     Data.den = new double[Data.numberOfPixels]; 
    } 
} 
class Program 
{ 
    static void Main(string[] args) 
    { 
     Method.RetrieveFileList(); 
     Method.CreatePositionArray(); 
     Method.InitializeBufferArray(); 
     Method.FillImageBuffer(); 
     for(int i = 0; i < Data.numberOfFrames; i++) 
     { 
      for (int j = 0; j < Data.numberOfPixels; j++) 
      { 
       double der = Math.Pow(Data.imageBuffer[i+1][j] - Data.imageBuffer[i][j], 2); 
       if (der < 1) der = 0; 
       Data.num[j] = Data.num[j] + Data.z[i] * der; 
       Data.den[j] = Data.den[j] + der; 
      } 
     } 
    } 
} 

具体地,在我的主要方法中的两个环。现在这个循环处理大约1000帧,每帧有1210000个像素。外循环的一次迭代大约需要80ms才能执行。 这里最好的方法是什么? 创建多个线程并将我的缓冲区分成预定义的垃圾或使用并行类? 我将不胜感激任何形式的帮助。

谢谢。

+0

这样工作吗? 'Data.imageBuffer [i + 1]'听起来像'IndexOutOfRangeException'给我。 –

回答

1

可能需要反向循环顺序来减少数组索引引用。此外,而不是Math.Pow(DER,2),更好地利用DER *德 - 这是一个快一点

 Method.RetrieveFileList(); 
    Method.CreatePositionArray(); 
    Method.InitializeBufferArray(); 
    Method.FillImageBuffer(); 
     for (int j = 0; j < Data.numberOfPixels; j++) { 
     double num = 0 
     double den = 0; 
     for(int i = 0; i < Data.numberOfFrames; i++) { 
      double der = Data.imageBuffer[i+1][j] - Data.imageBuffer[i][j]  
      if ((der *= der) < 1) der = 0; 
      num += Data.z[i] * der; 
      den += der; 
     } 
     Data.num[j] = num; 
     Data.den[j] = den; 
    } 

坦率地说,我不认为它会drammatically提高性能。

+0

我喜欢它! 'der = 0;'可以用'continue'替换,而顶部循环可以很容易地转换为'Parallel.For'。 +1 –

+0

谢谢,伊万。 Parallel.For是一种真正的感觉。另外...不喜欢“contunue”的人可以使用“if(der * der> = 1){num + = ...; den + =。}而是:) – cyanide

0

我一直在努力“循环太多”一段时间了,我也有同样的问题。我花了9100万次,花了我大约4-5分钟。我所做的将这个分解为20-30秒是分析。你必须尝试Visual Studio分析器。它确实可以帮助您了解哪一行代码会显着降低您的程序性能。我注意到没有人提到GPGPU(GPU上的一般编程/或类似的东西)。如果你想每帧执行你的代码,GPGPU可以做到!您可以使用OpenCL,Cudafy或DirectX/OpenGL的计算着色器。如果您不想进行GPU编程,那么使用VS Profiler是您的最佳实践。