线程速度越来越慢是怎么回事?

时间:2020-12-18 18:35:17
电脑为4核心。我的一个程序使用了4个子线程进行数据分析,目的是为了提高运行速度。最近在程序中增加了一些新的子线程,与前面4个子线程毫无关系,并且不会与他们程同时执行。前面的4个线程运行速度越来越慢了,找不到原因。请高手指点,谢谢!

9 个解决方案

#1


4核心,这就意味着最多同时只能执行4个线程,其它都在那里排队、来回来去地抢cpu玩呢!如果你在一个程序中使用cpu进行计算、并不空闲的时候还要滥用线程,那么多线程编程肯定让你的程序变得很慢!

当然具体要分析代码,这些只是启发原则而已。

#2


电脑为4核心。

你的程序,确定是分在四个不同核心中运行了吗???


我没记 错的话,默认还是全在一个核心是运行的,故而^^^^^^


除非你特意写多核心程序,

且记:多线程,与多核心是不同的.

嘻嘻.




#3


引用 1 楼 sp1234 的回复:
4核心,这就意味着最多同时只能执行4个线程,其它都在那里排队、来回来去地抢cpu玩呢!如果你在一个程序中使用cpu进行计算、并不空闲的时候还要滥用线程,那么多线程编程肯定让你的程序变得很慢!

当然具体要分析代码,这些只是启发原则而已。


前面我所说的那4个线程是耗时最大的线程,我在程序中刻意控制只要执行这4个线程,其它线程都不能执行。另外也没有其它程序运行,执行者4个线程前,CPU占用率为0。应该是在执行时出了问题——要处理的数据有多组(如1-10组),每组都用4个线程同时处理,现在在处理第1组数据是CPU占用率只有25%,以后逐步增加;排在后面的组数据量指数增加,随着数据量增加CPU占用率可达到92%。现在明显变慢的是处理前几组数据的时候。以前处理第一组数据,根本就感觉不到,处理第2组数据,可以看见(进度条)一闪即过。如今处理第1组数据也要消耗大概1秒钟。(注:处理第10组数据的速度和以前,基本没什么变化)实在是搞不明白了。问题出在哪里了呢

#4


没代码没真相,LZ应该Profiling代码

#5


引用 4 楼 wo65432519 的回复:
没代码没真相,LZ应该Profiling代码

代码太长,下面节选线程控制部分

注:线程中的程序没问题,我觉得问题应该出现在线程的处理上,难道我这样处理会受到其它干扰?
    Private Sub ThreadsEnd()'每个线程结束都要首先到达这里,以控制同一组数据分析同时开始(处理过程没有同步要求)
        If Th0EndFlag AndAlso Th1EndFlag AndAlso Th2EndFlag AndAlso Th3EndFlag Then
            '这里判断哪一组计算完成,并把已完成的组做上标记(代码略)
            ConventionCalculate() '调用线程控制
        End If
    End Sub

    Private Sub ConventionCalculate()'所有线程都在这里控制
        If Not RedOneEnd AndAlso RedOneUsed Then ’线程控制——处理第1组数据
            th0 = New Thread(AddressOf OneCode)
            th0.Start()
            th1 = New Thread(AddressOf OneCode1)
            th1.Start()
            th2 = New Thread(AddressOf OneCode2)
            th2.Start()
            th3 = New Thread(AddressOf OneCode3)
            th3.Start()
        ElseIf Not RedTwoEnd AndAlso RedTwoUsed Then’线程控制——处理第2组数据
            th0 = New Thread(AddressOf TwoCode)
            th0.Start()
            th1 = New Thread(AddressOf TwoCode1)
            th1.Start()
            th2 = New Thread(AddressOf TwoCode2)
            th2.Start()
            th3 = New Thread(AddressOf TwoCode3)
            th3.Start()
            
            '代码类似——略

        ElseIf Not RedTenEnd AndAlso RedTenUsed Then’线程控制——处理第10组数据
            th0 = New Thread(AddressOf TenCode)
            th0.Start()
            th1 = New Thread(AddressOf TenCode1)
            th1.Start()
            th2 = New Thread(AddressOf TenCode2)
            th2.Start()
            th3 = New Thread(AddressOf TenCode3)
            th3.Start()
        Else
            '所有需要处理的数据全部完成,进行内存清理等。
        End If
    End Sub 


#6


1. 排在后面的组数据量指数增加,是数据量大到什么级别,检查是否存在大量的I/O?
2. 处理完成后线程没有完全退出,造成资源没有释放? 检查应用程序的线程数是否增长。

#7


引用 6 楼 dk385 的回复:
1. 排在后面的组数据量指数增加,是数据量大到什么级别,检查是否存在大量的I/O?
2. 处理完成后线程没有完全退出,造成资源没有释放? 检查应用程序的线程数是否增长。


没有任何I/O检查,全部是内存数据,第1组只有几十个数据,第10组有几十亿个数据

虽然完全退出线程,但是重新实例化了,线程数没有变。

关键是数据量大的时候速度降低1-5%,第1组数据处理的时候速度降低可能近百倍。找不到原因,头大了!

#8


另外,前面的线程控制代码至今没动过。只是增加一了些其它与此线程无关的功能代码之后,就成了这个样子。原来的速度都是飞快的。

#9


虽然没有完全退出线程,但是重新实例化了,线程数没有变。

#1


4核心,这就意味着最多同时只能执行4个线程,其它都在那里排队、来回来去地抢cpu玩呢!如果你在一个程序中使用cpu进行计算、并不空闲的时候还要滥用线程,那么多线程编程肯定让你的程序变得很慢!

当然具体要分析代码,这些只是启发原则而已。

#2


电脑为4核心。

你的程序,确定是分在四个不同核心中运行了吗???


我没记 错的话,默认还是全在一个核心是运行的,故而^^^^^^


除非你特意写多核心程序,

且记:多线程,与多核心是不同的.

嘻嘻.




#3


引用 1 楼 sp1234 的回复:
4核心,这就意味着最多同时只能执行4个线程,其它都在那里排队、来回来去地抢cpu玩呢!如果你在一个程序中使用cpu进行计算、并不空闲的时候还要滥用线程,那么多线程编程肯定让你的程序变得很慢!

当然具体要分析代码,这些只是启发原则而已。


前面我所说的那4个线程是耗时最大的线程,我在程序中刻意控制只要执行这4个线程,其它线程都不能执行。另外也没有其它程序运行,执行者4个线程前,CPU占用率为0。应该是在执行时出了问题——要处理的数据有多组(如1-10组),每组都用4个线程同时处理,现在在处理第1组数据是CPU占用率只有25%,以后逐步增加;排在后面的组数据量指数增加,随着数据量增加CPU占用率可达到92%。现在明显变慢的是处理前几组数据的时候。以前处理第一组数据,根本就感觉不到,处理第2组数据,可以看见(进度条)一闪即过。如今处理第1组数据也要消耗大概1秒钟。(注:处理第10组数据的速度和以前,基本没什么变化)实在是搞不明白了。问题出在哪里了呢

#4


没代码没真相,LZ应该Profiling代码

#5


引用 4 楼 wo65432519 的回复:
没代码没真相,LZ应该Profiling代码

代码太长,下面节选线程控制部分

注:线程中的程序没问题,我觉得问题应该出现在线程的处理上,难道我这样处理会受到其它干扰?
    Private Sub ThreadsEnd()'每个线程结束都要首先到达这里,以控制同一组数据分析同时开始(处理过程没有同步要求)
        If Th0EndFlag AndAlso Th1EndFlag AndAlso Th2EndFlag AndAlso Th3EndFlag Then
            '这里判断哪一组计算完成,并把已完成的组做上标记(代码略)
            ConventionCalculate() '调用线程控制
        End If
    End Sub

    Private Sub ConventionCalculate()'所有线程都在这里控制
        If Not RedOneEnd AndAlso RedOneUsed Then ’线程控制——处理第1组数据
            th0 = New Thread(AddressOf OneCode)
            th0.Start()
            th1 = New Thread(AddressOf OneCode1)
            th1.Start()
            th2 = New Thread(AddressOf OneCode2)
            th2.Start()
            th3 = New Thread(AddressOf OneCode3)
            th3.Start()
        ElseIf Not RedTwoEnd AndAlso RedTwoUsed Then’线程控制——处理第2组数据
            th0 = New Thread(AddressOf TwoCode)
            th0.Start()
            th1 = New Thread(AddressOf TwoCode1)
            th1.Start()
            th2 = New Thread(AddressOf TwoCode2)
            th2.Start()
            th3 = New Thread(AddressOf TwoCode3)
            th3.Start()
            
            '代码类似——略

        ElseIf Not RedTenEnd AndAlso RedTenUsed Then’线程控制——处理第10组数据
            th0 = New Thread(AddressOf TenCode)
            th0.Start()
            th1 = New Thread(AddressOf TenCode1)
            th1.Start()
            th2 = New Thread(AddressOf TenCode2)
            th2.Start()
            th3 = New Thread(AddressOf TenCode3)
            th3.Start()
        Else
            '所有需要处理的数据全部完成,进行内存清理等。
        End If
    End Sub 


#6


1. 排在后面的组数据量指数增加,是数据量大到什么级别,检查是否存在大量的I/O?
2. 处理完成后线程没有完全退出,造成资源没有释放? 检查应用程序的线程数是否增长。

#7


引用 6 楼 dk385 的回复:
1. 排在后面的组数据量指数增加,是数据量大到什么级别,检查是否存在大量的I/O?
2. 处理完成后线程没有完全退出,造成资源没有释放? 检查应用程序的线程数是否增长。


没有任何I/O检查,全部是内存数据,第1组只有几十个数据,第10组有几十亿个数据

虽然完全退出线程,但是重新实例化了,线程数没有变。

关键是数据量大的时候速度降低1-5%,第1组数据处理的时候速度降低可能近百倍。找不到原因,头大了!

#8


另外,前面的线程控制代码至今没动过。只是增加一了些其它与此线程无关的功能代码之后,就成了这个样子。原来的速度都是飞快的。

#9


虽然没有完全退出线程,但是重新实例化了,线程数没有变。