0

使用多个任务在单独的位图上绘图并结合单个任务时,性能没有提高的原因是什么?(见代码)

Private test1 As bitmap_drawer
Private test2 As bitmap_drawer
Private test3 As bitmap_drawer
Private test4 As bitmap_drawer
Private tmptime As String
Private tmptime_1 As DateTime
Private tmptime_2 As DateTime
Private tmptimespan_1 As New TimeSpan


Sub Main()

    Console.WriteLine("4 tasks (parallel) graphics.draw")

    test1 = New bitmap_drawer
    test2 = New bitmap_drawer
    test3 = New bitmap_drawer
    test4 = New bitmap_drawer

    tmptime_1 = DateTime.Now


    Dim action1 As Action(Of Object) = Sub(obj As Object)
                                           Console.WriteLine("Task={0}, Thread={1}", Task.CurrentId, Thread.CurrentThread.ManagedThreadId)
                                           test1.DoDrawing()
                                       End Sub
    Dim action2 As Action(Of Object) = Sub(obj As Object)
                                           Console.WriteLine("Task={0}, Thread={1}", Task.CurrentId, Thread.CurrentThread.ManagedThreadId)
                                           test2.DoDrawing()
                                       End Sub

    Dim action3 As Action(Of Object) = Sub(obj As Object)
                                           Console.WriteLine("Task={0}, Thread={1}", Task.CurrentId, Thread.CurrentThread.ManagedThreadId)
                                           test3.DoDrawing()
                                       End Sub

    Dim action4 As Action(Of Object) = Sub(obj As Object)
                                           Console.WriteLine("Task={0},  Thread={1}", Task.CurrentId, Thread.CurrentThread.ManagedThreadId)
                                           test4.DoDrawing()
                                       End Sub


    Dim t1 As New Task(action1, "1")
    Dim t2 As New Task(action2, "2")
    Dim t3 As New Task(action3, "3")
    Dim t4 As New Task(action4, "4")

    t1.Start()
    t2.Start()
    t3.Start()
    t4.Start()

    Do

    Loop Until t1.IsCompleted And t2.IsCompleted And t3.IsCompleted And t4.IsCompleted

    t1.Dispose()
    t2.Dispose()
    t3.Dispose()
    t4.Dispose()

    tmptime_2 = DateTime.Now
    tmptimespan_1 = (tmptime_2 - tmptime_1)
    tmptime = tmptimespan_1.Seconds.ToString & "sec  " & tmptimespan_1.Milliseconds.ToString & "msec"
    Console.WriteLine("   parallel total: " & tmptime)     ''time:  1sec 136ms


    ''++++++++++++++++++++++++++++++++++++++++++++++++++++++++

    Console.WriteLine("  ")
    Console.WriteLine("4 tasks (serial) graphics.draw")
    tmptime_1 = DateTime.Now

    test1.DoDrawing()
    test2.DoDrawing()
    test3.DoDrawing()
    test4.DoDrawing()


    tmptime_2 = DateTime.Now
    tmptimespan_1 = (tmptime_2 - tmptime_1)
    tmptime = tmptimespan_1.Seconds.ToString & "sec  " & tmptimespan_1.Milliseconds.ToString & "msec"
    Console.WriteLine("   serial total: " & tmptime)   ''time:  0sec 857ms

    ''Conclusion: Both methods generate almost same time

    Console.ReadKey()
End Sub

现在类 bitmapdrawer

Public Class bitmap_drawer

Private tmptime As String
Private tmptime_1 As DateTime
Private tmptime_2 As DateTime
Private tmptimespan_1 As New TimeSpan



Private drawing_parts() As drawing_part


Private g As Graphics
Public bm As Bitmap

Sub New()
    ''init drawing data array
    ReDim drawing_parts(124999)

    ''create drawing data
    MakeDrawingData()

    ''create a bitmap
    bm = New Bitmap(1000, 1000, Imaging.PixelFormat.Format32bppPArgb)
    ''create  graphics from the bitmap
    g = Graphics.FromImage(bm)

End Sub

Sub DoDrawing()
    Dim i As Int32
    tmptime_1 = DateTime.Now
    Dim drawing_pen As New Pen(Color.Black, 0)

    '' do the drawing on the bitmap
    For i = 0 To 124999
        g.DrawPath(drawing_pen, drawing_parts(i).pat)
    Next

    tmptime_2 = DateTime.Now
    tmptimespan_1 = (tmptime_2 - tmptime_1)
    tmptime = tmptimespan_1.Seconds.ToString & "sec  " & tmptimespan_1.Milliseconds.ToString & "msec"
    Console.WriteLine("                   " & tmptime)

End Sub

Private Sub MakeDrawingData()
    Dim x, y As Int32
    Dim i As Int32
    i = 0
    For y = 0 To 249
        For x = 0 To 249
            drawing_parts(i) = New drawing_part With {.pat = New GraphicsPath}
            drawing_parts(i).pat.AddRectangle(New Rectangle(New Point(6 * x, 6 * y), New Size(5, 5)))
            drawing_parts(i).pat.Flatten()
            i += 1
            drawing_parts(i) = New drawing_part With {.pat = New GraphicsPath}
            drawing_parts(i).pat.AddEllipse(6 * x, 6 * y, 8, 5)
            drawing_parts(i).pat.Flatten()
            i += 1
        Next
    Next


End Sub

结束类

现在类绘图部分

Public Class drawing_part


Private tmp_pat As GraphicsPath
Public Property pat() As GraphicsPath
    Get
        Return tmp_pat
    End Get
    Set(ByVal Value As GraphicsPath)
        tmp_pat = Value
    End Set
End Property

结束类

4

1 回答 1

1

GDI 操作是硬件加速的——即它使用 GPU 尽可能多地进行绘图。然而,GPU 是一个单一的硬件资源,由所有线程共享。因此,即使您有 4 个线程在合适的 CPU 上并行运行,GPU 仍然会完成这项工作。在多个任务之间切换也会产生开销。

但是,如果您的绘图操作有很多 CPU 使用率 - 例如准确计算要绘制的内容 - 那么并行化它可能是一个胜利。

于 2012-12-09T09:54:33.963 回答