# 昂贵的C＃操作，希望提高性能

My company is developing software for a product that does some rather expensive calculations using a film from an IR camera where every pixel contains a temperature value. The most costly of those methods is called Thermal Signal Reconstruction (if you are interested, you can read about it here https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4321698/ ). It basically performs a polynomial fit for each pixel over time (the number of frames). My C# implementation looks something like this:

``````public static double[,,] ThermalSignalReconstruction(List<Frame<double>> thermalFilm, byte polyOrder)
{
Resolution filmResolution = thermalFilm[0].Resolution;
uint width = filmResolution.Width;
uint height = filmResolution.Height;
int frames = thermalFilm.Count;
double[,,] result = new double[polyOrder + 1, height, width];

// using frame indexes as x-values for poly fit
List<double> frameIndexes = new List<double>(frames);
for (var frame = 0U; frame < frames; ++frame)

Parallel.For(0U, frames, frame =>
{
// (...) calculate difference images: subtract first frame from all others
});

Parallel.For(0U, frames, frame =>
{
// determine flashpoint: find frame with maximum average pixel value
});
// (...) remove frames preceeding flashpoint, including itself, from film

Parallel.For(0U, frames, frame =>
{
// calculate System.Math.Log10 of all pixels and frame indexes
});

// perform polynomial fit for each pixel
Parallel.For(0U, height, row =>
{
for (var col = 0U; col < width; ++col)
{
// extract poly fit input y-values for current pixel
double[] pixelValues = new double[frames];
for (var frame = 0U; frame < frames; ++frame)
pixelValues[frame] = localThermalFilm[(int)frame].Data[row, col];

// (...) do some value validations

// poly fit for current pixel - this is the longest step
double[] coefficients = Math.PolynomialRegression(frameIndexesValidated.ToArray(), pixelValuesValidated.ToArray(), polyOrder);

// insert into coefficient images result array
for (var coefficient = 0U; coefficient < result.GetLength(0); ++coefficient)
result[coefficient, row, col] = coefficients[coefficient];
}
});

return result;
}
``````

As you can see, several parallelized loops performing several operations on the frames are executed in sequence with the polynomial fit (Math.PolynomialRegression) being the last and most expensive one. This is a function containing a polynomial fit algorithm I pieced together myself since it doesn't exist in the standard System.Math library and the only other one I tried from the Math.NET library actually runs slower than the one I wrote. My code is based on examples given on Rosetta Code: https://rosettacode.org/wiki/Polynomial_regression

• 在依次运行和并行化各个循环之间进行切换，这是最快的，所有循环都如上所述并行化
• 调整由各个并行循环实例访问的变量（例如，每次访问同一分辨率对象时均不访问，而是在开始循环之前声明宽度和高度的单独变量），这已经使性能有了很大提高，但仍有48％之后
• 尝试使用Parallel.ForEach（Partitioner.Create（0，frames）...）方法，即使用Partitioner类对数据块进行更粗略的分区，这无济于事，使代码运行速度更慢
• 尽我所能优化其他调用的函数以及该调用方的代码