在这个例子中,为什么 VisualBasic (VB.NET) 比 C++ 代码快?
Why VisualBasic (VB.NET) faster than C++ code in this example?
我一直在对迭代计算进行基准测试,这是一个使用雅可比方法的静电拉帕拉斯方程求解器。我用 Visual Basic 和 C++(以及其他语言)编写了相同的算法。出于某种原因,Visual Basic .Net 是最快的。我不明白为什么。由于 C++ 被编译为字节码,因此我希望它更快。我觉得我的 C++ 可能没有得到应有的优化。任何有助于理解为什么 C++ 不比 VisualBasic 快的帮助将不胜感激。谢谢。
在以下代码中,Visual basic 的迭代循环持续约 2.8 秒,而 VisualC++ 需要 4.8 秒
Visual Basic 代码
Imports System.Timers
Module Module1
Const ARRAYDIM = 500
Const iterationVMaxError = 0.001
Sub Main()
Dim PAArrayPotentials(ARRAYDIM, ARRAYDIM) As Single
Dim PAArrayIsElectrode(ARRAYDIM, ARRAYDIM) As Boolean
Console.WriteLine("SpeedTestEMLaplaceSolverVB")
Console.WriteLine("Start generating electrodes and popuate 2D array")
'Start generating electrodes
For iy = 0 To ARRAYDIM - 1
For ix = 0 To ARRAYDIM - 1
PAArrayPotentials(iy, ix) = 0 'Default
PAArrayIsElectrode(iy, ix) = False
If ix = 20 And (iy > 150 And iy < 350) Then
PAArrayPotentials(iy, ix) = 1 'Default
PAArrayIsElectrode(iy, ix) = True
End If
If ix = 480 And (iy > 150 And iy < 350) Then
PAArrayPotentials(iy, ix) = -1 'Default
PAArrayIsElectrode(iy, ix) = True
End If
Next
Next
Console.WriteLine("Finished creating electrodes.")
Console.WriteLine("Press enter key to start")
Console.ReadLine()
Console.WriteLine("Starting iterative Laplace.")
Dim iteration As Integer = 0
Dim maxerror As Single = 0
Dim t0 = System.Diagnostics.Stopwatch.StartNew()
Do
maxerror = 0
For iy = 0 To ARRAYDIM - 1
For ix = 0 To ARRAYDIM - 1
If Not PAArrayIsElectrode(iy, ix) Then
Dim sum As Single = 0
Dim nvalues As Single = 0
If iy > 0 Then
sum += PAArrayPotentials(iy - 1, ix)
nvalues += 1
End If
If iy < ARRAYDIM - 1 Then
sum += PAArrayPotentials(iy + 1, ix)
nvalues += 1
End If
If ix > 0 Then
sum += PAArrayPotentials(iy, ix - 1)
nvalues += 1
End If
If ix < ARRAYDIM - 1 Then
sum += PAArrayPotentials(iy, ix + 1)
nvalues += 1
End If
If nvalues > 0 Then
Dim newval As Single = sum / nvalues
Dim vchange As Single = Math.Abs(newval - PAArrayPotentials(iy, ix))
maxerror = Math.Max(vchange, maxerror)
PAArrayPotentials(iy, ix) = newval
End If
End If
Next
Next
iteration += 1
Loop While maxerror > iterationVMaxError
Dim deltaT As Long = t0.ElapsedMilliseconds
Console.WriteLine("Completed, in " + iteration.ToString + " iteration cycles; deltat = " + deltaT.ToString + " miliseconds.")
Console.WriteLine("Press enter key to close")
Console.ReadLine()
End Sub
End Module
Visual C++ 代码
// SpeedTestEMLaplaceSolver2.cpp : This file contains the 'main' function. Program execution begins and ends there.
//
#include <iostream>
#include <array>
#include <cmath>
#include <chrono>
#define ARRAYDIM 500
//Use normal arrays rather than the std::array
float PAArrayPotentials[ARRAYDIM][ARRAYDIM];
bool PAArrayIsElectrode[ARRAYDIM][ARRAYDIM];
int main()
{
std::cout << "SpeedTestEMLaplaceSolver2.cpp using standard arrays float PAArrayPotentials[PAWIDTH][PAHEIGHT];\n";
std::cout << "500 x 500 with 2 electrodes at position 20 and 480. Height of 200 each.\n" <<
"Left electrode at + 1 V and right electrode at - 1V.\n" <<
"iterationVMaxError = 1e-3.\n";
const float iterationVMaxError = 1e-3f;
//Fill array with zeros and electrodes
std::cout << "Start generating electrodes and PA.\n";
for (int iy = 0; iy < ARRAYDIM; iy++) {
for (int ix = 0; ix < ARRAYDIM; ix++) {
float * pmyPointPot = &PAArrayPotentials[iy][ix]; //get a reference to the point
bool * pmyPointIsEl = &PAArrayIsElectrode[iy][ix]; //get a reference to the point
//Default for all points
*pmyPointPot = 0;
*pmyPointIsEl = false;
//Electrode
if (ix == 20 && (iy > 150 && iy < 350 )) {
*pmyPointPot = 1;
*pmyPointIsEl = true;
}
if (ix == 480 && (iy > 20 && iy < 350 ) ) {
*pmyPointPot = -1;
*pmyPointIsEl = true;
}
}
}
std::cout << "Completed generating electrodes and PA.\n";
std::cout << "Type a letter and enter key to start calculation.\n";
char stemp[80];
std::cin >> stemp;
std::cout << "Start iterative laplace\n";
auto starttime = std::chrono::steady_clock::now();
long iteration = 0;
float perror;
//Convergence routine
do {
perror = 0; //resets
for (int iy = 0; iy < ARRAYDIM; iy++) {
for (int ix = 0; ix < ARRAYDIM; ix++) {
if (!PAArrayIsElectrode[iy][ix]) {
//Makes the new value the average of surrounding values
float sum = 0;
float nvalues = 0;
if (iy > 0) {
sum += PAArrayPotentials[iy - 1][ix];
nvalues++;
}
if (iy < ARRAYDIM - 1) {
sum += PAArrayPotentials[iy + 1][ix];
nvalues++;
}
if (ix > 0) {
sum += PAArrayPotentials[iy][ix - 1];
nvalues++;
}
if (ix < ARRAYDIM - 1) {
sum += PAArrayPotentials[iy][ix + 1];
nvalues++;
}
if (nvalues > 0) {
float newVal = sum / nvalues;
float vchange = fabs(newVal - PAArrayPotentials[iy][ix]);
perror = fmax(vchange, perror);
PAArrayPotentials[iy][ix] = newVal; //Set the new calculated value
}
}
}
}
iteration++;
//std::cout << "iteration: " << iteration << " , perror= " << perror << std::endl;
} while (perror > iterationVMaxError );
auto endtime = std::chrono::steady_clock::now();
std::cout << "Completed, in " << iteration << " iteration cycles; deltat = " << std::chrono::duration_cast<std::chrono::milliseconds>(endtime - starttime).count() << " miliseconds" << std::endl;
return 0;
}
好的。在进一步研究 VB.Net 比 C++ 快的原因后,我假设问题可能是由于 C++ 编译器造成的。
我下载了英特尔C++编译器并重新编译了程序。
我还将数组更改为 1024x1024 大小,并将停止迭代的条件更改为 maxchange=1e-4。全部在 MS Visual Studio 2019 社区下开发。
基准测试结果为:
Visual C++ (MS): 66356 miliseconds
Visual C++ (Intel): 39013 miliseconds
VB.Net : 62847 miliseconds
所以,现在 C++ 编译代码 (intel) 更快。
这是我使用的代码
// SpeedTestEMLaplaceSolver2.cpp : This file contains the 'main' function. Program execution begins and ends there.
//
#include <iostream>
#include <array>
#include <cmath>
#include <chrono>
#define ARRAYDIM 1024
//Use normal arrays rather than the std::array
float PAArrayPotentials[ARRAYDIM][ARRAYDIM];
bool PAArrayIsElectrode[ARRAYDIM][ARRAYDIM];
int main()
{
const float iterationVMaxError = 1e-4f;
std::cout << "SpeedTestEMLaplaceSolver2.cpp using standard arrays float PAArrayPotentials[PAWIDTH][PAHEIGHT];\n";
std::cout << "Dimensions: " << ARRAYDIM << "x" << ARRAYDIM << " , iterationVMaxError = " << iterationVMaxError << "\n" <<
"Left electrode at + 1 V and right electrode at - 1V.\n";
const int pos_1_4 = (int)floor(ARRAYDIM / 4);
const int pos_3_4 = (int)floor(ARRAYDIM * 3 / 4);
//Fill array with zeros and electrodes
std::cout << "Start generating electrodes and PA.\n";
for (int iy = 0; iy < ARRAYDIM; iy++) {
for (int ix = 0; ix < ARRAYDIM; ix++) {
float * pmyPointPot = &PAArrayPotentials[iy][ix]; //get a reference to the point
bool * pmyPointIsEl = &PAArrayIsElectrode[iy][ix]; //get a reference to the point
//Default for all points
*pmyPointPot = 0;
*pmyPointIsEl = false;
//Electrode
if (ix == pos_1_4 && (iy > pos_1_4 && iy < pos_3_4)) {
*pmyPointPot = 1;
*pmyPointIsEl = true;
}
if (ix == pos_3_4 && (iy > pos_1_4 && iy < pos_3_4) ) {
*pmyPointPot = -1;
*pmyPointIsEl = true;
}
}
}
std::cout << "Completed generating electrodes and PA.\n";
std::cout << "Type a letter and enter key to start calculation.\n";
char stemp[80];
std::cin >> stemp;
std::cout << "Start iterative laplace\n";
auto starttime = std::chrono::steady_clock::now();
long iteration = 0;
float maxerror =0;
//Convergence routine
do {
maxerror = 0; //resets
for (int iy = 0; iy < ARRAYDIM; iy++) {
for (int ix = 0; ix < ARRAYDIM; ix++) {
if (!PAArrayIsElectrode[iy][ix]) {
//Makes the new value the average of surrounding values
float sum = 0;
float nvalues = 0;
if (iy > 0) {
sum += PAArrayPotentials[iy - 1][ix];
nvalues++;
}
if (iy < ARRAYDIM - 1) {
sum += PAArrayPotentials[iy + 1][ix];
nvalues++;
}
if (ix > 0) {
sum += PAArrayPotentials[iy][ix - 1];
nvalues++;
}
if (ix < ARRAYDIM - 1) {
sum += PAArrayPotentials[iy][ix + 1];
nvalues++;
}
if (nvalues > 0) {
float newVal = sum / nvalues;
float vchange = fabs(newVal - PAArrayPotentials[iy][ix]);
maxerror = fmax(vchange, maxerror);
PAArrayPotentials[iy][ix] = newVal; //Set the new calculated value
}
}
}
}
iteration++;
//std::cout << "iteration: " << iteration << " , perror= " << perror << std::endl;
} while (maxerror > iterationVMaxError );
auto endtime = std::chrono::steady_clock::now();
std::cout << "Completed, in " << iteration << " iteration cycles; deltat = " << std::chrono::duration_cast<std::chrono::milliseconds>(endtime - starttime).count() << " miliseconds" << std::endl;
return 0;
}
还有 VB.Net
Imports System.Timers
Module Module1
Const ARRAYDIM = 1024
Const iterationVMaxError = 0.0001 ' 1e-4
Sub Main()
Dim PAArrayPotentials(ARRAYDIM - 1, ARRAYDIM - 1) As Single
Dim PAArrayIsElectrode(ARRAYDIM - 1, ARRAYDIM - 1) As Boolean
Console.WriteLine("SpeedTestEMLaplaceSolverVB")
Console.WriteLine("Dimensions: " + ARRAYDIM.ToString + "x" + ARRAYDIM.ToString + " , iterationVMaxError = " + iterationVMaxError.ToString)
Console.WriteLine("Start generating electrodes and popuate 2D array")
Dim pos_1_4 As Integer = Int(ARRAYDIM / 4)
Dim pos_3_4 As Integer = Int(ARRAYDIM * 3 / 4)
'Start generating electrodes
For iy = 0 To ARRAYDIM - 1
For ix = 0 To ARRAYDIM - 1
PAArrayPotentials(iy, ix) = 0 'Default
PAArrayIsElectrode(iy, ix) = False
If ix = pos_1_4 And (iy > pos_1_4 And iy < pos_3_4) Then
PAArrayPotentials(iy, ix) = 1 'Default
PAArrayIsElectrode(iy, ix) = True
End If
If ix = pos_3_4 And (iy > pos_1_4 And iy < pos_3_4) Then
PAArrayPotentials(iy, ix) = -1 'Default
PAArrayIsElectrode(iy, ix) = True
End If
Next
Next
Console.WriteLine("Finished creating electrodes.")
Console.WriteLine("Press enter key to start")
Console.ReadLine()
Console.WriteLine("Starting iterative Laplace.")
Dim iteration As Integer = 0
Dim maxerror As Single = 0
Dim t0 = System.Diagnostics.Stopwatch.StartNew()
Do
maxerror = 0
For iy = 0 To ARRAYDIM - 1
For ix = 0 To ARRAYDIM - 1
If Not PAArrayIsElectrode(iy, ix) Then
Dim sum As Single = 0
Dim nvalues As Single = 0
If iy > 0 Then
sum += PAArrayPotentials(iy - 1, ix)
nvalues += 1
End If
If iy < ARRAYDIM - 1 Then
sum += PAArrayPotentials(iy + 1, ix)
nvalues += 1
End If
If ix > 0 Then
sum += PAArrayPotentials(iy, ix - 1)
nvalues += 1
End If
If ix < ARRAYDIM - 1 Then
sum += PAArrayPotentials(iy, ix + 1)
nvalues += 1
End If
If nvalues > 0 Then
Dim newval As Single = sum / nvalues
Dim vchange As Single = Math.Abs(newval - PAArrayPotentials(iy, ix))
maxerror = Math.Max(vchange, maxerror)
PAArrayPotentials(iy, ix) = newval
End If
End If
Next
Next
iteration += 1
Loop While maxerror > iterationVMaxError
Dim deltaT As Long = t0.ElapsedMilliseconds
Console.WriteLine("Completed, in " + iteration.ToString + " iteration cycles; deltat = " + deltaT.ToString + " miliseconds.")
Console.WriteLine("Press enter key to close")
Console.ReadLine()
End Sub
End Module
我一直在对迭代计算进行基准测试,这是一个使用雅可比方法的静电拉帕拉斯方程求解器。我用 Visual Basic 和 C++(以及其他语言)编写了相同的算法。出于某种原因,Visual Basic .Net 是最快的。我不明白为什么。由于 C++ 被编译为字节码,因此我希望它更快。我觉得我的 C++ 可能没有得到应有的优化。任何有助于理解为什么 C++ 不比 VisualBasic 快的帮助将不胜感激。谢谢。
在以下代码中,Visual basic 的迭代循环持续约 2.8 秒,而 VisualC++ 需要 4.8 秒
Visual Basic 代码
Imports System.Timers
Module Module1
Const ARRAYDIM = 500
Const iterationVMaxError = 0.001
Sub Main()
Dim PAArrayPotentials(ARRAYDIM, ARRAYDIM) As Single
Dim PAArrayIsElectrode(ARRAYDIM, ARRAYDIM) As Boolean
Console.WriteLine("SpeedTestEMLaplaceSolverVB")
Console.WriteLine("Start generating electrodes and popuate 2D array")
'Start generating electrodes
For iy = 0 To ARRAYDIM - 1
For ix = 0 To ARRAYDIM - 1
PAArrayPotentials(iy, ix) = 0 'Default
PAArrayIsElectrode(iy, ix) = False
If ix = 20 And (iy > 150 And iy < 350) Then
PAArrayPotentials(iy, ix) = 1 'Default
PAArrayIsElectrode(iy, ix) = True
End If
If ix = 480 And (iy > 150 And iy < 350) Then
PAArrayPotentials(iy, ix) = -1 'Default
PAArrayIsElectrode(iy, ix) = True
End If
Next
Next
Console.WriteLine("Finished creating electrodes.")
Console.WriteLine("Press enter key to start")
Console.ReadLine()
Console.WriteLine("Starting iterative Laplace.")
Dim iteration As Integer = 0
Dim maxerror As Single = 0
Dim t0 = System.Diagnostics.Stopwatch.StartNew()
Do
maxerror = 0
For iy = 0 To ARRAYDIM - 1
For ix = 0 To ARRAYDIM - 1
If Not PAArrayIsElectrode(iy, ix) Then
Dim sum As Single = 0
Dim nvalues As Single = 0
If iy > 0 Then
sum += PAArrayPotentials(iy - 1, ix)
nvalues += 1
End If
If iy < ARRAYDIM - 1 Then
sum += PAArrayPotentials(iy + 1, ix)
nvalues += 1
End If
If ix > 0 Then
sum += PAArrayPotentials(iy, ix - 1)
nvalues += 1
End If
If ix < ARRAYDIM - 1 Then
sum += PAArrayPotentials(iy, ix + 1)
nvalues += 1
End If
If nvalues > 0 Then
Dim newval As Single = sum / nvalues
Dim vchange As Single = Math.Abs(newval - PAArrayPotentials(iy, ix))
maxerror = Math.Max(vchange, maxerror)
PAArrayPotentials(iy, ix) = newval
End If
End If
Next
Next
iteration += 1
Loop While maxerror > iterationVMaxError
Dim deltaT As Long = t0.ElapsedMilliseconds
Console.WriteLine("Completed, in " + iteration.ToString + " iteration cycles; deltat = " + deltaT.ToString + " miliseconds.")
Console.WriteLine("Press enter key to close")
Console.ReadLine()
End Sub
End Module
Visual C++ 代码
// SpeedTestEMLaplaceSolver2.cpp : This file contains the 'main' function. Program execution begins and ends there.
//
#include <iostream>
#include <array>
#include <cmath>
#include <chrono>
#define ARRAYDIM 500
//Use normal arrays rather than the std::array
float PAArrayPotentials[ARRAYDIM][ARRAYDIM];
bool PAArrayIsElectrode[ARRAYDIM][ARRAYDIM];
int main()
{
std::cout << "SpeedTestEMLaplaceSolver2.cpp using standard arrays float PAArrayPotentials[PAWIDTH][PAHEIGHT];\n";
std::cout << "500 x 500 with 2 electrodes at position 20 and 480. Height of 200 each.\n" <<
"Left electrode at + 1 V and right electrode at - 1V.\n" <<
"iterationVMaxError = 1e-3.\n";
const float iterationVMaxError = 1e-3f;
//Fill array with zeros and electrodes
std::cout << "Start generating electrodes and PA.\n";
for (int iy = 0; iy < ARRAYDIM; iy++) {
for (int ix = 0; ix < ARRAYDIM; ix++) {
float * pmyPointPot = &PAArrayPotentials[iy][ix]; //get a reference to the point
bool * pmyPointIsEl = &PAArrayIsElectrode[iy][ix]; //get a reference to the point
//Default for all points
*pmyPointPot = 0;
*pmyPointIsEl = false;
//Electrode
if (ix == 20 && (iy > 150 && iy < 350 )) {
*pmyPointPot = 1;
*pmyPointIsEl = true;
}
if (ix == 480 && (iy > 20 && iy < 350 ) ) {
*pmyPointPot = -1;
*pmyPointIsEl = true;
}
}
}
std::cout << "Completed generating electrodes and PA.\n";
std::cout << "Type a letter and enter key to start calculation.\n";
char stemp[80];
std::cin >> stemp;
std::cout << "Start iterative laplace\n";
auto starttime = std::chrono::steady_clock::now();
long iteration = 0;
float perror;
//Convergence routine
do {
perror = 0; //resets
for (int iy = 0; iy < ARRAYDIM; iy++) {
for (int ix = 0; ix < ARRAYDIM; ix++) {
if (!PAArrayIsElectrode[iy][ix]) {
//Makes the new value the average of surrounding values
float sum = 0;
float nvalues = 0;
if (iy > 0) {
sum += PAArrayPotentials[iy - 1][ix];
nvalues++;
}
if (iy < ARRAYDIM - 1) {
sum += PAArrayPotentials[iy + 1][ix];
nvalues++;
}
if (ix > 0) {
sum += PAArrayPotentials[iy][ix - 1];
nvalues++;
}
if (ix < ARRAYDIM - 1) {
sum += PAArrayPotentials[iy][ix + 1];
nvalues++;
}
if (nvalues > 0) {
float newVal = sum / nvalues;
float vchange = fabs(newVal - PAArrayPotentials[iy][ix]);
perror = fmax(vchange, perror);
PAArrayPotentials[iy][ix] = newVal; //Set the new calculated value
}
}
}
}
iteration++;
//std::cout << "iteration: " << iteration << " , perror= " << perror << std::endl;
} while (perror > iterationVMaxError );
auto endtime = std::chrono::steady_clock::now();
std::cout << "Completed, in " << iteration << " iteration cycles; deltat = " << std::chrono::duration_cast<std::chrono::milliseconds>(endtime - starttime).count() << " miliseconds" << std::endl;
return 0;
}
好的。在进一步研究 VB.Net 比 C++ 快的原因后,我假设问题可能是由于 C++ 编译器造成的。
我下载了英特尔C++编译器并重新编译了程序。 我还将数组更改为 1024x1024 大小,并将停止迭代的条件更改为 maxchange=1e-4。全部在 MS Visual Studio 2019 社区下开发。
基准测试结果为:
Visual C++ (MS): 66356 miliseconds
Visual C++ (Intel): 39013 miliseconds
VB.Net : 62847 miliseconds
所以,现在 C++ 编译代码 (intel) 更快。
这是我使用的代码
// SpeedTestEMLaplaceSolver2.cpp : This file contains the 'main' function. Program execution begins and ends there.
//
#include <iostream>
#include <array>
#include <cmath>
#include <chrono>
#define ARRAYDIM 1024
//Use normal arrays rather than the std::array
float PAArrayPotentials[ARRAYDIM][ARRAYDIM];
bool PAArrayIsElectrode[ARRAYDIM][ARRAYDIM];
int main()
{
const float iterationVMaxError = 1e-4f;
std::cout << "SpeedTestEMLaplaceSolver2.cpp using standard arrays float PAArrayPotentials[PAWIDTH][PAHEIGHT];\n";
std::cout << "Dimensions: " << ARRAYDIM << "x" << ARRAYDIM << " , iterationVMaxError = " << iterationVMaxError << "\n" <<
"Left electrode at + 1 V and right electrode at - 1V.\n";
const int pos_1_4 = (int)floor(ARRAYDIM / 4);
const int pos_3_4 = (int)floor(ARRAYDIM * 3 / 4);
//Fill array with zeros and electrodes
std::cout << "Start generating electrodes and PA.\n";
for (int iy = 0; iy < ARRAYDIM; iy++) {
for (int ix = 0; ix < ARRAYDIM; ix++) {
float * pmyPointPot = &PAArrayPotentials[iy][ix]; //get a reference to the point
bool * pmyPointIsEl = &PAArrayIsElectrode[iy][ix]; //get a reference to the point
//Default for all points
*pmyPointPot = 0;
*pmyPointIsEl = false;
//Electrode
if (ix == pos_1_4 && (iy > pos_1_4 && iy < pos_3_4)) {
*pmyPointPot = 1;
*pmyPointIsEl = true;
}
if (ix == pos_3_4 && (iy > pos_1_4 && iy < pos_3_4) ) {
*pmyPointPot = -1;
*pmyPointIsEl = true;
}
}
}
std::cout << "Completed generating electrodes and PA.\n";
std::cout << "Type a letter and enter key to start calculation.\n";
char stemp[80];
std::cin >> stemp;
std::cout << "Start iterative laplace\n";
auto starttime = std::chrono::steady_clock::now();
long iteration = 0;
float maxerror =0;
//Convergence routine
do {
maxerror = 0; //resets
for (int iy = 0; iy < ARRAYDIM; iy++) {
for (int ix = 0; ix < ARRAYDIM; ix++) {
if (!PAArrayIsElectrode[iy][ix]) {
//Makes the new value the average of surrounding values
float sum = 0;
float nvalues = 0;
if (iy > 0) {
sum += PAArrayPotentials[iy - 1][ix];
nvalues++;
}
if (iy < ARRAYDIM - 1) {
sum += PAArrayPotentials[iy + 1][ix];
nvalues++;
}
if (ix > 0) {
sum += PAArrayPotentials[iy][ix - 1];
nvalues++;
}
if (ix < ARRAYDIM - 1) {
sum += PAArrayPotentials[iy][ix + 1];
nvalues++;
}
if (nvalues > 0) {
float newVal = sum / nvalues;
float vchange = fabs(newVal - PAArrayPotentials[iy][ix]);
maxerror = fmax(vchange, maxerror);
PAArrayPotentials[iy][ix] = newVal; //Set the new calculated value
}
}
}
}
iteration++;
//std::cout << "iteration: " << iteration << " , perror= " << perror << std::endl;
} while (maxerror > iterationVMaxError );
auto endtime = std::chrono::steady_clock::now();
std::cout << "Completed, in " << iteration << " iteration cycles; deltat = " << std::chrono::duration_cast<std::chrono::milliseconds>(endtime - starttime).count() << " miliseconds" << std::endl;
return 0;
}
还有 VB.Net
Imports System.Timers
Module Module1
Const ARRAYDIM = 1024
Const iterationVMaxError = 0.0001 ' 1e-4
Sub Main()
Dim PAArrayPotentials(ARRAYDIM - 1, ARRAYDIM - 1) As Single
Dim PAArrayIsElectrode(ARRAYDIM - 1, ARRAYDIM - 1) As Boolean
Console.WriteLine("SpeedTestEMLaplaceSolverVB")
Console.WriteLine("Dimensions: " + ARRAYDIM.ToString + "x" + ARRAYDIM.ToString + " , iterationVMaxError = " + iterationVMaxError.ToString)
Console.WriteLine("Start generating electrodes and popuate 2D array")
Dim pos_1_4 As Integer = Int(ARRAYDIM / 4)
Dim pos_3_4 As Integer = Int(ARRAYDIM * 3 / 4)
'Start generating electrodes
For iy = 0 To ARRAYDIM - 1
For ix = 0 To ARRAYDIM - 1
PAArrayPotentials(iy, ix) = 0 'Default
PAArrayIsElectrode(iy, ix) = False
If ix = pos_1_4 And (iy > pos_1_4 And iy < pos_3_4) Then
PAArrayPotentials(iy, ix) = 1 'Default
PAArrayIsElectrode(iy, ix) = True
End If
If ix = pos_3_4 And (iy > pos_1_4 And iy < pos_3_4) Then
PAArrayPotentials(iy, ix) = -1 'Default
PAArrayIsElectrode(iy, ix) = True
End If
Next
Next
Console.WriteLine("Finished creating electrodes.")
Console.WriteLine("Press enter key to start")
Console.ReadLine()
Console.WriteLine("Starting iterative Laplace.")
Dim iteration As Integer = 0
Dim maxerror As Single = 0
Dim t0 = System.Diagnostics.Stopwatch.StartNew()
Do
maxerror = 0
For iy = 0 To ARRAYDIM - 1
For ix = 0 To ARRAYDIM - 1
If Not PAArrayIsElectrode(iy, ix) Then
Dim sum As Single = 0
Dim nvalues As Single = 0
If iy > 0 Then
sum += PAArrayPotentials(iy - 1, ix)
nvalues += 1
End If
If iy < ARRAYDIM - 1 Then
sum += PAArrayPotentials(iy + 1, ix)
nvalues += 1
End If
If ix > 0 Then
sum += PAArrayPotentials(iy, ix - 1)
nvalues += 1
End If
If ix < ARRAYDIM - 1 Then
sum += PAArrayPotentials(iy, ix + 1)
nvalues += 1
End If
If nvalues > 0 Then
Dim newval As Single = sum / nvalues
Dim vchange As Single = Math.Abs(newval - PAArrayPotentials(iy, ix))
maxerror = Math.Max(vchange, maxerror)
PAArrayPotentials(iy, ix) = newval
End If
End If
Next
Next
iteration += 1
Loop While maxerror > iterationVMaxError
Dim deltaT As Long = t0.ElapsedMilliseconds
Console.WriteLine("Completed, in " + iteration.ToString + " iteration cycles; deltat = " + deltaT.ToString + " miliseconds.")
Console.WriteLine("Press enter key to close")
Console.ReadLine()
End Sub
End Module