2011-01-26 6 views
0

입력으로 텍스트 파일을 받고 출력으로 다른 텍스트 파일을 반환하는 프로그램을 작성했습니다. 텍스트 파일은 3D 응용 프로그램 (Blender) 내에 스크립트 (파이썬)로 생성되며 정사각형 메쉬의 일부인 정점 목록을 포함합니다. 프로그램은 그 데이터를 받아 구조체에 저장하고 작은 정사각형을 형성하는 정점 목록을 반환합니다. 스크립트를 사용하는 3D 앱은이 꼭지점을 읽고 원래의 메쉬와 분리합니다. 이 작업을 여러 번 수행하면 원래 메쉬가 같은 영역의 여러 사각형으로 나뉩니다.멀티 스레딩 C 언어의 구조체 배열

#include <stdio.h> 
#include <stdlib.h> 
#include <malloc.h> 
typedef struct{ 
    int index; 
    float x,y,z; 
} vertex; 
vertex *find_vertex(vertex *list, int len) 
{ 
    int i; 
    vertex lower,highter; 
    lower=list[0]; 
    highter=list[1]; 
//find the lower lefter and the upper righter vertices 
    for(i=0;i<len;i++) 
    { 
     if ((list[i].x<=lower.x) && (list[i].y<=lower.y)) 
      lower=list[i]; 
     if ((list[i].x>=highter.x) && (list[i].y>=highter.y)) 
      highter=list[i]; 
    } 
    vertex *ret;//create a pointer for returning 2 structs 
    ret=(vertex*)malloc(sizeof(vertex)*2); 
    if (ret==NULL) 
    { 
     printf("Can't allocate the memory"); 
     return 0; 
    } 
    ret[0]=lower; 
    ret[1]=highter; 
    return ret; 
} 
vertex *square_list_of_vertex(vertex *list,int len,vertex start, float size) 
{ 
    int i=0,a=0; 
    unsigned int *num; 
    num=(int*)malloc(sizeof(unsigned int)*len); 
    if (num==NULL) 
    { 
     printf("Can't allocate the memory"); 
     return 0; 
    } 
    //controlls if point is in the right position and adds its index in the main list in another array 
    for(i=0;i<len;i++) 
    { 
     if ((list[i].x-start.x)<size && (list[i].y-start.y<size)) 
     { 
      if (list[i].y-start.y>-size/100)//it was adding also wrong vertices. This line is to solve a bug 
      { 
       num[a]=i; 
       a++;//len of the return list 
      } 
     } 
    } 
    //create the list with the right vertices 
    vertex *retlist; 
    retlist=(vertex*)malloc(sizeof(vertex)*(a+1)); 
    if (retlist==NULL) 
    { 
     printf("Can't allocate the memory"); 
     return 0; 
    } 
    //the first index is used only as an info container 
    vertex infos; 
    infos.index=a+1; 
    retlist[0]=infos; 
    //set the value for the return pointer 
    for(i=1;i<=a;i++) 
    { 
     retlist[i]=list[num[i-1]]; 
    } 
    return retlist; 
} 
//the function that pass the data to python 
void return_funct_1(vertex lower,vertex highter) 
{ 
    FILE* ret; 
    ret=fopen("max_min.txt","w"); 
    if (ret==NULL) 
    { 
     printf("Error opening the file\n"); 
     return; 
    } 
    fprintf(ret,"%i\n",lower.index); 
    fprintf(ret,"%i\n",highter.index); 
    fclose(ret); 
} 
//the function that pass the data to python 
void return_funct_2(vertex *squarelist) 
{ 
    FILE* ret; 
    int i,len; 
    ret=fopen("square_list.txt","w"); 
    if (ret==NULL) 
    { 
     printf("Error opening the file\n"); 
     return; 
    } 
    len=squarelist[0].index; 
    for(i=1;i<len;i++) 
    { 
     //return all the informations 
     //fprintf(ret,"%i %f %f %f\n",squarelist[i].index,squarelist[i].x,squarelist[i].y,squarelist[i].z); 

     //just return the index(it's enought for the python script) 
     fprintf(ret,"%i\n",squarelist[i].index); 
    } 
    fclose(ret); 
} 
//argv: 
//function[1/2] number_of_vert(int) size_of_square(int) v_index(int) v_xcoord(float) v_ycoord(float) v_zcoord(float)... 
//example of file: 2 4 2 0 1 2 3 1 1 2 3 2 1 2 3 3 1 2 3 4 1 2 3 //function 1, number of ver=4, size=2 and then the 4 vertex with their coords 
int main(int argc, char *argv[]) 
{ 
    if(argc==1) 
    { 
     printf("%s need a path to a vectorlist file\n",argv[0]); 
     return 0; 
    } 
    FILE* input; 
    input=fopen(argv[1],"r"); 
    if (input==NULL) 
    { 
     printf("Error opening the file\n"); 
     return(0); 
    } 
    int func=0,i=0,a=0,u=0; 
    char read; 
    char* argument; 
    argument=(char*)malloc(sizeof(char)*50);//yeah, i know, i should use list instead of an array, but when i first coded this i was quite in hurry (and i'm still learning) 
    //get the first paramater in the file 
    argument[0]=fgetc(input); 
    argument[1]='\0'; 
    func=atoi(argument); 
    //skipp the space 
    read=fgetc(input); 
    //get the number of vertices; 
    i=0; 
    do { 
     read=fgetc(input); 
     argument[i]=read; 
     i++; 
    }while(read!=' ' && !feof(input)); 
    //set the end of the string 
    argument[i]='\0'; 
    //set the variable to the correct integer value; 
    int vnumber=atoi(argument); 
    i=0; 
    do { 
     read=fgetc(input); 
     argument[i]=read; 
     i++; 
    } while(read!=' ' && !feof(input)); 
    //set the end of the string 
    argument[i]='\0'; 
    float sqsize=atof(argument); 
    vertex *list; 
    //allocate memory in the array to fit the number of vertex needed 
    list=(vertex*)malloc(sizeof(vertex)*vnumber); 
    //control if the memory get allocated 
    if (list==NULL) 
    { 
     printf("Can't allocate the memory"); 
     return 0; 
    } 
    //do the cycle for each vertex 
    for(u=0;u<vnumber;u++) 
    { 
     //read the number and assign it to the proper value of the vertex 
     for(a=0;a<4;a++) 
     { 
      i=0; 
      do 
      { 
       read=fgetc(input); 
       argument[i]=read; 
       i++; 
      } while(read!=' ' && !feof(input)); 
      argument[i]='\0'; 

      if(a==0) 
       list[u].index=atoi(argument); 
      if(a==1) 
       list[u].x=atof(argument); 
      if(a==2) 
       list[u].y=atof(argument); 
      if(a==3) 
       list[u].z=atof(argument); 
     } 
    } 
    //close the file 
    fclose(input); 
    if (func==1) 
    { 
     //find the lowest vertex and the higtest vertex 
     vertex lower; 
     vertex highter; 
     vertex *lohi; 
     lohi=(vertex*)find_vertex(list, vnumber); 
     lower=lohi[0]; 
     highter=lohi[1]; 
     free(lohi); 
     return_funct_1(lower,highter);//the function that return the data to python 
     return 1; 
    } 
    if(func==2) 
    { 
     //find the list to return 
     vertex *lohi; 
     lohi=(vertex*)find_vertex(list, vnumber); 
     vertex lower; 
     lower=lohi[0]; 
     free(lohi); 
     return_funct_2(square_list_of_vertex(list,vnumber, lower, sqsize));//the function that return the data to python 
     return 1; 
    } 
    printf("Function argument was wrong: nothing was done\n"); 
} 

: 그것은 시간이 걸립니다 20 만 개 정점에 그 일을하지만, 1kk 정점에 실행이 시대 여기

소스를 취하면 ..) 그러나 몹시 낮다, 지금까지 는 IT 작동 난 정말이 멀티 스레드 만들기위한 모든 도움을 주셔서 감사합니다. 그것은 정말 큰 데이터 (오늘 나는 50mb 텍스트 파일로 노력하고, 20 분 후 30 일만 (26000 내가 필요한)에서 실행했다 노력에 나이가 소요됩니다.), 그리고 이것을 사용하는 모든 PC가 적어도 4 개의 코어를 갖기 때문에, 나는 그것을 멀티 스레드로 만들고 싶습니다! 조언에 감사드립니다! :)

Ps : 필요한 경우 Python 스크립트 코드도 게시 할 수 있지만 프로그램의 내부 API 호출이 너무 꽉 차서 실제로 유용할지 여부는 알 수 없습니다.

+0

여기 * 구체적인 * 질문은 무엇입니까? –

+0

질문은 : "이걸 다중 스레드로 만들 수있게 도와 줄 수 있니?" –

+0

@ 그렉 : 아주 구체적인 질문은 아니지만! –

답변

0

코드를 통해 구체적으로 작업하지는 않겠지 만 알고리즘이지도 및 축소를 적용 할 수 있습니다. 나는 소스 파일과 함께 2 개 백만 임의 정점의 샘플 데이터 세트를 통해 실행되는 코드를 프로파일 링 할 때

http://pages.cs.wisc.edu/~gibson/mapReduceTutorial.html

0

이 페이지에 미리로드 :

는 C에서 사용할 수있는 방법의 기사입니다 캐시 병목 현상은 문자열을 실수로 변환하는 것입니다 (그래도 여전히 5 초 만에 실행됩니다. 따라서 이 아니기 때문에이 느림).

문자열의 변환을 부동 소수점으로 멀티 스레드 할 수 있으며 신중한 코딩으로 이러한 방식으로 이득을 얻을 수 있습니다. 그러나 C 코드 (fread())로 직접로드 할 수있는 이진 형식으로 부동 소수점 숫자를 쓰도록 Python 코드를 변경하는 경우에는 더 많은 돈을 벌 수 있습니다. 나는 이것을 달성하기 위해 파이썬 측에서 struct.pack을 사용할 수 있다고 생각한다.

코드의 처리 부분도 확실히 개선 될 수 있지만 병목 현상이 발생할 때까지는 걱정할 필요가 없습니다.

+0

감사합니다. 정말 고마워요! 파이썬으로 bin 파일을 저장하는 법을 배우겠다. Ps : 코드를 프로파일 링하는 데 사용한 프로그램은 무엇입니까? –

+0

@Makers_F : [Perf] (https://perf.wiki.kernel.org/index.php/Main_Page)를 사용했습니다. – caf