最近,我一直在用C ++和VB.NET运行一些测试来比较执行速度。在last thread I posted中,我谈到了我如何遇到C ++执行速度与VB一样快的事实,但是解决了这个问题。现在我正撞在另一面墙上:
我为VB.NET制作了一个DLL来测试这个理论,并在一个程序中比较相同的VB.NET和C ++代码的执行时间。但有趣的是什么? VB.NET的执行时间得到了改进,现在它与C ++的执行时间完全相同。花了一些时间解决这个问题,我发现Visual Studio 2008中高级编译选项中的“目标CPU”选项是罪魁祸首!
由于我正在运行64位Windows 7,因此我认为目标CPU x64会产生最佳执行时间。错误。以下是用于VB.NET的Windows窗体应用程序执行时间的结果,计算高达10,000,000的所有素数并得到它们的总和。
任何CPU:15.231秒
x86:10.858秒
x64:15.236秒
以下是我正在使用的代码,您可以自行测试:
Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim watch As New Stopwatch
watch.Start()
Dim maxVal As Long = 10000000
Dim sumOfPrimes As Long = 0
For i As Integer = 2 To maxVal
If (isPrime(i) = True) Then
sumOfPrimes += i
End If
Next
watch.Stop()
Console.WriteLine(watch.ElapsedMilliseconds)
Console.WriteLine("The sum of all the prime numbers below " & maxVal & " is " & sumOfPrimes)
End Sub
Function isPrime(ByVal NumToCheck As Integer) As Boolean
For i As Integer = 2 To (Math.Sqrt(CDbl(NumToCheck)))
If (NumToCheck Mod i = 0) Then
Return False
End If
Next
Return True
End Function
End Class
为什么在运行64位时将目标CPU选为32位会导致性能提升?对此问题的任何帮助将不胜感激。
答案 0 :(得分:2)
32位和64位模式之间存在许多差异,这可能会以某种方式扭曲性能差异。
在64位模式下,CPU有更多的寄存器,每个寄存器都更大,这使得某些操作的执行速度更快(例如,更高的寄存器数可能会避免存储器访问)
但32位也至少有一个优势:
指针为32位宽,64位模式下为64位。对于严重依赖指针的程序,这可能导致64位模式下显着更高的内存使用率,这意味着程序数据的一小部分将适合CPU缓存,因此在64位模式下性能可能会降低,因此更高的缓存未命中数。
另一个因素是.NET框架在这两方面都不是同样出色。它们在32位和64位版本的CLR之间尚未具有功能奇偶校验,并且对于64位代码,JIT可能也不像32位情况那样进行调整。
答案 1 :(得分:0)
.NET 3.5 SP1(即Visual Studio 2008 SP1)带来了许多性能增强功能,让JIT:er内联更有效。不幸的是,这些增强功能仅针对x86:
How are value types implemented in the 32-bit CLR? What has been done to improve their performance?
然而,在.NET 4.0中,我发现x64和x86现在可以为x64提供相同或更好的性能。
答案 2 :(得分:0)
我在发布模式下运行以下代码。我使用 Ctrl + F5 来运行代码。
Public Class Form1
Function isPrime(ByVal NumToCheck As Integer) As Boolean
Dim limit As Integer = CInt(Math.Ceiling(Math.Sqrt(CDbl(NumToCheck))))
For i As Integer = 2 To limit
If (NumToCheck Mod i = 0) Then
Return False
End If
Next
Return True
End Function
Dim watch As New Stopwatch
Private Sub Button1_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Button1.Click
watch.Reset()
watch.Start()
Dim maxVal As Integer = 2000000
Dim sumOfPrimes As Long = 0
For i As Integer = 2 To maxVal
If isPrime(i) Then
sumOfPrimes += i
End If
Next
watch.Stop()
Label1.Text = watch.ElapsedMilliseconds.ToString
Label2.Text = "The sum of all the prime numbers below " & maxVal & " is " & sumOfPrimes
End Sub
End Class
AnyCPU每次都比x86快。我使用的是.NET 4.0。