python单进程能否利用多核cpu的测试结论

在很早的时候,就听网上的文章说:

python有GIL,所以在单进程内,即使使用多线程也无法利用到多核的优势,同一时刻,python的字节码只会运行在一个cpu上。

以前也是奉为真理,直到今天在对自己的python server做性能测试的时候,发现一个python进程的cpu居然达到了120%。

当用c++编程的时候,如果使用多线程,那么确实进程cpu超过100%非常正常,但是对python来说,似乎这样就和网上的文章冲突了。

所以还是决定自己亲身试验一下,编写代码如下:

from thread import start_new_threaddef worker():    while 1:        #print 1        passfor it in range(0, 15):    start_new_thread(worker, ())raw_input()

?

运行环境为: centos6.4 64位, python 2.7.

得到的结果如下:

可以清楚的看到,pid为31199的python进程cpu达到了787.9%,接近理论能达到的最大值 800%。

而上方的8个cpu也分别达到了近100%的利用率。

?

如果只是按照以上测试结果,确实可以得出的结论:python使用单进程,多线程确实能够使用到多核cpu,并不是网上传的结论。

但是,还是希望如果有读者对这块有更深入的研究能够进行批评指正,谢谢~


8月15日补充

感谢 la.onger 等几位博友的讨论,现在增加一个测试,用来测试纯cpu计算用一个线程or多个线程完成的总时间的差别,代码如下:

import timefrom threading import ThreadLOOPS = 1000000THREAD_NUM = 10STEP_SIZE = 94753434class Test(object):    num = 1    def work(self):        for it in xrange(0, LOOPS):            if self.num > STEP_SIZE:                self.num -= STEP_SIZE            else:                self.num += STEP_SIZE    def one_thread_test(self):        self.num = 1        begin_time = time.time()        for v in xrange(0, THREAD_NUM):            self.work()        print 'time passed: ', time.time() - begin_time    def multi_thread_test(self):        self.num = 1        t_list = []        begin_time = time.time()        for v in xrange(0, THREAD_NUM):            t = Thread(target=self.work)            t.start()            t_list.append(t)        for it in t_list:            it.join()        print 'time passed: ', time.time() - begin_timet = Test()t.one_thread_test()t.multi_thread_test()

输入结果如下:

time passed:  3.44264101982time passed:  7.22910785675

使用多线程后,比不用多线程还慢

?

为了与c++版做对比,也开发了c++代码如下:

#include <stdio.h>#include <string.h>#include <stdint.h>#include <iostream>#include <memory>#include <sstream>#include <algorithm>#include <string>#include <vector>#include <set>#include <map>#include <sys/time.h>#include <pthread.h>using namespace std;#define LOOPS 1000000#define THREAD_NUM 10#define STEP_SIZE   94753434class Test{public:    Test() {}    virtual ~Test() {}    void one_thread_test() {        this->num = 1;        gettimeofday(&m_tpstart,NULL);        for (size_t i = 0; i < THREAD_NUM; ++i)        {            work();        }        gettimeofday(&m_tpend,NULL);        long long timeuse=1000000*(long long)(m_tpend.tv_sec-m_tpstart.tv_sec)+m_tpend.tv_usec-m_tpstart.tv_usec;//微秒        printf("time passed: %f\n", ((double)timeuse) / 1000000);    }    void multi_thread_test() {        this->num = 1;        int ret;        vector<pthread_t> vecThreadId;//所有thread的id        pthread_attr_t attr;        pthread_attr_init (&attr);        pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);        gettimeofday(&m_tpstart,NULL);        pthread_t threadId;        for (int i = 0; i < THREAD_NUM; i++)        {            ret= pthread_create(&threadId, &attr, Test::static_run_work, (void*)this);            if(ret!=0){                pthread_attr_destroy (&attr);            }            vecThreadId.push_back(threadId);        }        pthread_attr_destroy (&attr);        for(vector<pthread_t>::iterator it = vecThreadId.begin(); it != vecThreadId.end(); ++it)        {            pthread_join(*it, NULL);        }        gettimeofday(&m_tpend,NULL);        long long timeuse=1000000*(long long)(m_tpend.tv_sec-m_tpstart.tv_sec)+m_tpend.tv_usec-m_tpstart.tv_usec;//微秒        printf("time passed: %f\n", ((double)timeuse) / 1000000);    }    void work() {        for (size_t i = 0; i < LOOPS; ++i) {            if (this->num > STEP_SIZE) {                this->num -= STEP_SIZE;            }            else {                this->num += STEP_SIZE;            }        }    }    static void* static_run_work(void *args) {        Test* t = (Test*) args;        t->work();        return NULL;    }public:    int64_t num;    struct timeval m_tpstart,m_tpend;};int main(int argc, char **argv){    Test test;    test.one_thread_test();    test.multi_thread_test();    return 0;}

输出结果如下:

time passed: 0.036114time passed: 0.000513

可见,c++版确实性能提高了非常多。

?

由此可见,python的多线程编程,在多核cpu利用上确实差一些。

python单进程能否利用多核cpu的测试结论

相关文章:

你感兴趣的文章:

标签云: