游戏开发论坛

 找回密码
 立即注册
搜索
查看: 4985|回复: 6

[求助]关于多线程与多核CPU使用率

[复制链接]

227

主题

1793

帖子

1866

积分

金牌会员

Rank: 6Rank: 6

积分
1866
发表于 2009-10-14 10:37:00 | 显示全部楼层 |阅读模式

我用phtread尝试写了个渲染和逻辑分离的简易小程序……发现实际上只用了一个cpu核心……哪位前辈能帮忙看看原因么?压缩包里面有源代码

http://www.oz01.com/p/pthread_Test.zip

19

主题

40

帖子

128

积分

注册会员

Rank: 2

积分
128
发表于 2009-10-14 13:34:00 | 显示全部楼层

Re: [求助]关于多线程与多核CPU使用率

关键在于你的datastream这个函数做的事情太小了, 加上一个锁去串行化, 跟display这个函数基本上没有并行的可能, 所以只能用一个cpu, 如果要用2个cpu的话, 首先, 锁只能锁住改变2个参数的地方, 然后做一些与那2个参数无关的计算工作

0

主题

398

帖子

577

积分

高级会员

Rank: 4

积分
577
发表于 2009-10-14 14:57:00 | 显示全部楼层

Re:[求助]关于多线程与多核CPU使用率

我没下载文件。如果你把渲染放到一个独立线程中,那么这个线程可能只占用很少的CPU资源...以至于TaskMgr检测不到。

227

主题

1793

帖子

1866

积分

金牌会员

Rank: 6Rank: 6

积分
1866
 楼主| 发表于 2009-10-14 16:02:00 | 显示全部楼层

Re: Re: [求助]关于多线程与多核CPU使用率

zx9597446: Re: [求助]关于多线程与多核CPU使用率

关键在于你的datastream这个函数做的事情太小了, 加上一个锁去串行化, 跟display这个函数基本上没有并行的...

我没理解错的话,是要在datastream这个函数里多做些其他事?

227

主题

1793

帖子

1866

积分

金牌会员

Rank: 6Rank: 6

积分
1866
 楼主| 发表于 2009-10-14 16:03:00 | 显示全部楼层

Re: Re:[求助]关于多线程与多核CPU使用率

artint: Re:[求助]关于多线程与多核CPU使用率

我没下载文件。如果你把渲染放到一个独立线程中,那么这个线程可能只占用很少的CPU资源...以至于TaskMgr检测不到。

源代码:
/*
When creating your project, uncheck OWL,
uncheck Class Library, select Static
instead of Dynamic and change the target
model to Console from GUI.
Also link glut.lib to your project once its done.
*/

#include <windows.h>   // Standard Header For Most Programs
#include <GL/glew.h>
#include <GL/gl.h>     // The GL Header File
#include <GL/freeglut.h>   // The GL Utility Toolkit (Glut) Header
#include <pthread.h>
#include "dinput.h"
#include "dinputd.h"
#include <commctrl.h>
#pragma comment( lib, "dinput8.lib" )       
#pragma comment( lib, "comctl32.lib" )       
#pragma comment( lib, "pthreadVC2.lib" )       
#pragma comment( lib, "glew32.lib" )       
#pragma comment( lib, "glew32d.lib" )
float        rtri;                                                // Angle For The Triangle
float        rquad;                                                // Angle For The Quad
int winW=800;
int winH=600;
pthread_mutex_t mutex;
struct timespec delay;
IDirectInput8 *g_pDInputInterface; //dinput interface
IDirectInputDevice8 *g_pKeyboardDevice; //keyboard device
void* DataFream(void* Param)
{
        while(true)
        {
         pthread_mutex_lock( &mutex );
   rtri+=0.2f;                                                // Increase The Rotation Variable For The Triangle ( NEW )
        rquad-=0.15f;                                                // Decrease The Rotation Variable For The Quad     ( NEW )
        pthread_mutex_unlock( &mutex );
        pthread_delay_np( &delay );
        }
        return NULL;
}
void InitGL ( GLvoid )     // Create Some Everyday Functions
{

        glShadeModel(GL_SMOOTH);                                                        // Enable Smooth Shading
        glClearColor(0.0f, 0.0f, 0.0f, 0.5f);                                // Black Background
        glClearDepth(1.0f);                                                                        // Depth Buffer Setup
        glEnable(GL_DEPTH_TEST);                                                        // Enables Depth Testing
        glDepthFunc(GL_LEQUAL);                                                                // The Type Of Depth Testing To Do
        glEnable ( GL_COLOR_MATERIAL );
        glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
}

void display ( void )   // Create The Display Function
{
        float turn1,turn2;

        pthread_mutex_lock( &mutex );
        turn1=rtri;
        turn2=rquad;
        pthread_mutex_unlock( &mutex );
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);        // Clear Screen And Depth Buffer
   glLoadIdentity();                                                                        // Reset The Current Modelview Matrix
   glPushMatrix();
        glTranslatef(-1.5f,0.0f,-6.0f);                                                // Move Left 1.5 Units And Into The Screen 6.0
   glRotatef(turn1,0.0f,1.0f,0.0f);                                // Rotate The Triangle On The Y axis
   glEnable(GL_MULTISAMPLE_ARB);
        glBegin(GL_TRIANGLES);                                                                // Drawing Using Triangles
                glColor3f(1.0f,0.0f,0.0f);                        // Red
                glVertex3f( 0.0f, 1.0f, 0.0f);                        // Top Of Triangle (Front)
                glColor3f(0.0f,1.0f,0.0f);                        // Green
                glVertex3f(-1.0f,-1.0f, 1.0f);                        // Left Of Triangle (Front)
                glColor3f(0.0f,0.0f,1.0f);                        // Blue
                glVertex3f( 1.0f,-1.0f, 1.0f);                        // Right Of Triangle (Front)
                glColor3f(1.0f,0.0f,0.0f);                        // Red
                glVertex3f( 0.0f, 1.0f, 0.0f);                        // Top Of Triangle (Right)
                glColor3f(0.0f,0.0f,1.0f);                        // Blue
                glVertex3f( 1.0f,-1.0f, 1.0f);                        // Left Of Triangle (Right)
                glColor3f(0.0f,1.0f,0.0f);                        // Green
                glVertex3f( 1.0f,-1.0f, -1.0f);                        // Right Of Triangle (Right)
      glColor3f(1.0f,0.0f,0.0f);                        // Red
                glVertex3f( 0.0f, 1.0f, 0.0f);                        // Top Of Triangle (Back)
                glColor3f(0.0f,1.0f,0.0f);                        // Green
                glVertex3f( 1.0f,-1.0f, -1.0f);                        // Left Of Triangle (Back)
                glColor3f(0.0f,0.0f,1.0f);                        // Blue
                glVertex3f(-1.0f,-1.0f, -1.0f);                        // Right Of Triangle (Back)
                glColor3f(1.0f,0.0f,0.0f);                        // Red
                glVertex3f( 0.0f, 1.0f, 0.0f);                        // Top Of Triangle (Left)
                glColor3f(0.0f,0.0f,1.0f);                        // Blue
                glVertex3f(-1.0f,-1.0f,-1.0f);                        // Left Of Triangle (Left)
                glColor3f(0.0f,1.0f,0.0f);                        // Green
                glVertex3f(-1.0f,-1.0f, 1.0f);                        // Right Of Triangle (Left)
    glEnd();                                                                                        // Finished Drawing The Triangle
glDisable(GL_MULTISAMPLE_ARB);
        glLoadIdentity();                                        // Reset The Current Modelview Matrix
    glTranslatef(1.5f,0.0f,-6.0f);                                // Move Right 1.5 Units And Into The Screen 6.0
        glRotatef(turn2,1.0f,0.0f,0.0f);                        // Rotate The Quad On The X axis
        glColor3f(0.5f,0.5f,1.0f);                                                        // Set The Color To Blue One Time Only
        glBegin(GL_QUADS);                                                                        // Draw A Quad
                glColor3f(0.0f,1.0f,0.0f);                        // Set The Color To Blue
                glVertex3f( 1.0f, 1.0f,-1.0f);                        // Top Right Of The Quad (Top)
                glVertex3f(-1.0f, 1.0f,-1.0f);                        // Top Left Of The Quad (Top)
                glVertex3f(-1.0f, 1.0f, 1.0f);                        // Bottom Left Of The Quad (Top)
                glVertex3f( 1.0f, 1.0f, 1.0f);                        // Bottom Right Of The Quad (Top)
                glColor3f(1.0f,0.5f,0.0f);                        // Set The Color To Orange
                glVertex3f( 1.0f,-1.0f, 1.0f);                        // Top Right Of The Quad (Bottom)
                glVertex3f(-1.0f,-1.0f, 1.0f);                        // Top Left Of The Quad (Bottom)
                glVertex3f(-1.0f,-1.0f,-1.0f);                        // Bottom Left Of The Quad (Bottom)
                glVertex3f( 1.0f,-1.0f,-1.0f);                        // Bottom Right Of The Quad (Bottom)
                glColor3f(1.0f,0.0f,0.0f);                        // Set The Color To Red
                glVertex3f( 1.0f, 1.0f, 1.0f);                        // Top Right Of The Quad (Front)
                glVertex3f(-1.0f, 1.0f, 1.0f);                        // Top Left Of The Quad (Front)
                glVertex3f(-1.0f,-1.0f, 1.0f);                        // Bottom Left Of The Quad (Front)
                glVertex3f( 1.0f,-1.0f, 1.0f);                        // Bottom Right Of The Quad (Front)
                glColor3f(1.0f,1.0f,0.0f);                        // Set The Color To Yellow
                glVertex3f( 1.0f,-1.0f,-1.0f);                        // Bottom Left Of The Quad (Back)
                glVertex3f(-1.0f,-1.0f,-1.0f);                        // Bottom Right Of The Quad (Back)
                glVertex3f(-1.0f, 1.0f,-1.0f);                        // Top Right Of The Quad (Back)
                glVertex3f( 1.0f, 1.0f,-1.0f);                        // Top Left Of The Quad (Back)
                glColor3f(0.0f,0.0f,1.0f);                        // Set The Color To Blue
                glVertex3f(-1.0f, 1.0f, 1.0f);                        // Top Right Of The Quad (Left)
                glVertex3f(-1.0f, 1.0f,-1.0f);                        // Top Left Of The Quad (Left)
                glVertex3f(-1.0f,-1.0f,-1.0f);                        // Bottom Left Of The Quad (Left)
                glVertex3f(-1.0f,-1.0f, 1.0f);                        // Bottom Right Of The Quad (Left)
                glColor3f(1.0f,0.0f,1.0f);                        // Set The Color To Violet
                glVertex3f( 1.0f, 1.0f,-1.0f);                        // Top Right Of The Quad (Right)
                glVertex3f( 1.0f, 1.0f, 1.0f);                        // Top Left Of The Quad (Right)
                glVertex3f( 1.0f,-1.0f, 1.0f);                        // Bottom Left Of The Quad (Right)
                glVertex3f( 1.0f,-1.0f,-1.0f);                        // Bottom Right Of The Quad (Right)
        glEnd();                                                // Done Drawing The Quad
                                                                                                  // Done Drawing The Quad
  glPopMatrix();
  // rtri+=0.2f;                                                // Increase The Rotation Variable For The Triangle ( NEW )
        //rquad-=0.15f;                                                // Decrease The Rotation Variable For The Quad     ( NEW )


  glutSwapBuffers ( );
  // Swap The Buffers To Not Be Left With A Clear Screen
}

void reshape ( int width , int height )   // Create The Reshape Function (the viewport)
{
  if (height==0)                                                                                // Prevent A Divide By Zero By
        {
                height=1;                                                                                // Making Height Equal One
        }

        glViewport(0,0,width,height);                                                // Reset The Current Viewport

        glMatrixMode(GL_PROJECTION);                                                // Select The Projection Matrix
        glLoadIdentity();                                                                        // Reset The Projection Matrix

        // Calculate The Aspect Ratio Of The Window
        gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);

        glMatrixMode(GL_MODELVIEW);                                                        // Select The Modelview Matrix
        glLoadIdentity();                                                                       
}

void keyboard ( unsigned char key, int x, int y )  // Create Keyboard Function
{
  switch ( key ) {
    case 27:        // When Escape Is Pressed...
      exit ( 0 );   // Exit The Program
      break;        // Ready For Next Case
    default:        // Now Wrap It Up
      break;
  }
}

void arrow_keys ( int a_keys, int x, int y )  // Create Special Function (required for arrow keys)
{
  switch ( a_keys ) {
    case GLUT_KEY_UP:     // When Up Arrow Is Pressed...
      glutFullScreen ( ); // Go Into Full Screen Mode
      break;
    case GLUT_KEY_DOWN:               // When Down Arrow Is Pressed...
                glutFullScreen();
                glutPositionWindow((GetSystemMetrics(SM_CXFULLSCREEN)-winW)/2,(GetSystemMetrics(SM_CYFULLSCREEN)-winH)/2);
      glutReshapeWindow ( winW, winH ); // Go Into A 500 By 500 Window
          
      break;
    default:
      break;
  }
}


//void main ( int argc, char** argv )   // Create Main Function For Bringing It All Together
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
        InitCommonControls();
        char path[_MAX_PATH];
    GetModuleFileName(hInstance, path, _MAX_PATH);
        char* argv=(char *)path;
        delay.tv_nsec=10000000;
        delay.tv_sec=0;
     pthread_t pid;
     pthread_attr_t attr;
     pthread_attr_init(&attr);
     pthread_attr_setscope(&attr, PTHREAD_SCOPE_PROCESS);
     pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
        pthread_t reader;
        pthread_mutex_init(&mutex, NULL);
    pthread_create( &reader, &attr, DataFream,
                    NULL);
        glutInit            ( &nCmdShow, &argv ); // Erm Just Write It =)
//        glutInitDisplayMode ( GLUT_RGBA | GLUT_DOUBLE|GLUT_DEPTH|GLUT_MULTISAMPLE ); // Display Mode
        glutInitDisplayString("rgba double depth>=24 samples alpha");
        glutSetOption(GLUT_MULTISAMPLE,2);
        glutInitWindowPosition((GetSystemMetrics(SM_CXFULLSCREEN)-winW)/2,(GetSystemMetrics(SM_CYFULLSCREEN)-winH)/2);
        glutInitWindowSize  ( winW, winH ); // If glutFullScreen wasn't called this is the window size
        glutCreateWindow    ( "TOP_ACE" ); // Window Title (argv[0] for current directory as title)
//        glutFullScreen      ( );          // Put Into Full Screen
        InitGL ();
        glutDisplayFunc     ( display );  // Matching Earlier Functions To Their Counterparts
        glutReshapeFunc     ( reshape );
        glutKeyboardFunc    ( keyboard );
        glutSpecialFunc     ( arrow_keys );
        glutIdleFunc                  ( display );
        glutMainLoop        ( );          // Initialize The Main Loop
        return 0;
}

19

主题

40

帖子

128

积分

注册会员

Rank: 2

积分
128
发表于 2009-10-14 17:32:00 | 显示全部楼层

Re: Re: Re: [求助]关于多线程与多核CPU使用率

oz01: Re: Re: [求助]关于多线程与多核CPU使用率


我没理解错的话,是要在datastream这个函数里多做些其他事?

是的, 跟display()无关的事情, 才能尽量的并行起来
请参考herb sutter的关于多核、并行的系列文章

2

主题

123

帖子

123

积分

注册会员

Rank: 2

积分
123
发表于 2009-10-14 22:39:00 | 显示全部楼层

Re:[求助]关于多线程与多核CPU使用率

void* DataFream(void* Param)做的事情太少,锁太频繁了。
同步会破坏并行,锁越少越好。理想的并行是线程间通过异步消息通信,几乎不锁。

现在新的显卡驱动已经有了对多核的优化,应用程序对图形API的调用填充命令队列,之后命令队列由其它线程处理。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-6-20 03:03

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表