2017-07-21 3 views
1

Donc, je suis un noob quand il s'agit de ce genre de choses.Alternative à shed_getaffinity, cpu_set_t etc?

Je me bats pour compiler un modèle climatique sur macOS et je l'ai bouilli jusqu'à ce qui se passe ici:

#define _GNU_SOURCE 

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <unistd.h> 
#include <sched.h> 
#include <errno.h> 
#include <sys/resource.h> 
#include <sys/syscall.h> 

static pid_t gettid(void) 
{ 
    return syscall(__NR_gettid); 
} 

/*                                                         
* Returns this thread's CPU affinity, if bound to a single core,                                         
* or else -1.   




*/ 
int get_cpu_affinity(void) 
{ 
    cpu_set_t coremask;   /* core affinity mask */ 

    CPU_ZERO(&coremask); 
    if (sched_getaffinity(gettid(),sizeof(cpu_set_t),&coremask) != 0) { 
    fprintf(stderr,"Unable to get thread %d affinity. 

%s\n",gettid(),strerror(errno)); 
    } 

    int cpu; 
    int first_cpu = -1; /* first CPU in range */ 
    int last_cpu = -1; /* last CPU in range */ 
    for (cpu=0;cpu < CPU_SETSIZE;cpu++) { 
    if (CPU_ISSET(cpu,&coremask)) { 
     if (first_cpu == -1) { 
     first_cpu = cpu; 
     } else { 
     last_cpu = cpu; 
     } 
    } 
    } 

    return (last_cpu == -1) ? first_cpu : -1; 

} 

int get_cpu_affinity_(void) { return get_cpu_affinity(); }  /* Fortran interface */ 


/*                                                         
* Set CPU affinity to one core.                                                 
*/ 

void set_cpu_affinity(int cpu) 
{ 
    cpu_set_t coremask;   /* core affinity mask */ 

    CPU_ZERO(&coremask); 
    CPU_SET(cpu,&coremask); 
    if (sched_setaffinity(gettid(),sizeof(cpu_set_t),&coremask) != 0) { 
    fprintf(stderr,"Unable to set thread %d affinity. %s\n",gettid(),strerror(errno)); 

    } 
} 

void set_cpu_affinity_(int *cpu) { set_cpu_affinity(*cpu); } /* Fortran interface */ 

Lors de la compilation je reçois quelques erreurs:

Première - l'identifiant "cpu_set_t" est indéfini, Second - identifiant "CPU_SETSIZE" est indéfini

J'ai fait mon googling et il me semble que sched_getaffinitiy(), cpu_set_t et peut-être d'autres choses ne sont pas présentes dans macOS.

Avec toutes sortes de programmation en C, je suis vraiment hors de ma portée. Je me demandais si quelqu'un ici savait d'une autre façon de faire cela pour macOS et comment je pourrais y arriver.

J'ai joint le rapport d'erreur complet ci-dessous.

Cordialement,

Neil :)

Rapport complet d'erreur:

(python2) salvare:MASTERS Neil$ python run.py 
Working directory for exp 'playground' already exists 
RRTM compilation disabled. Namelist set to gray radiation. 
Writing path_names to '/Users/Neil/MASTERS/ISCA_TEMP/playground/path_names' 
Running compiler 
/Users/Neil/MASTERS/ISCA_TEMP/playground/compile.sh: line 21: module: command not found 
loadmodules 
/Users/Neil/MASTERS/Isca/src/extra/loadmodule: line 3: module: command not found 
/Users/Neil/MASTERS/Isca/src/extra/loadmodule: line 4: module: command not found 
/Users/Neil/MASTERS/Isca/src/extra/loadmodule: line 5: module: command not found 
/Users/Neil/MASTERS/Isca/src/extra/loadmodule: line 6: module: command not found 
/Users/Neil/MASTERS/ISCA_TEMP/playground/compile.sh: line 23: module: command not found 
/Users/Neil/MASTERS/ISCA_TEMP/playground/compile.sh: line 24: ulimit: stack size: cannot modify limit: Operation not permitted 
./compile_mppn.sh: line 13: module: command not found 
./compile_mppn.sh: line 14: module: command not found 
./compile_mppn.sh: line 15: module: command not found 
- mppnccombine.c:162:24: warning: format string is not a string literal (potentially insecure) [-Wformat-security] 
sprintf(outfilename,argv[outputarg]); outlen=strlen(outfilename); 
^~~~~~~~~~~~~~~ 
/usr/include/secure/_stdio.h:47:56: note: expanded from macro 'sprintf' 
__builtin___sprintf_chk (str, 0, __darwin_obsz(str), __VA_ARGS__) 
^~~~~~~~~~~ 
mppnccombine.c:162:24: note: treat the string as an argument to avoid this 
sprintf(outfilename,argv[outputarg]); outlen=strlen(outfilename); 
^ 
"%s", 
/usr/include/secure/_stdio.h:47:56: note: expanded from macro 'sprintf' 
__builtin___sprintf_chk (str, 0, __darwin_obsz(str), __VA_ARGS__) 
^ 
1 warning generated. 
ln: /Users/Neil/MASTERS/ISCA_TEMP/playground/exec/mppnccombine.x: File exists 
Makefile is ready. 
mpicc -Duse_libMPI -Duse_netCDF -Duse_LARGEFILE -DINTERNAL_FILE_NML -DOVERLOAD_C8 -DRRTM_NO_COMPILE -I/usr/local/include -D__IFC -c /Users/Neil/MASTERS/Isca/src/shared/mpp/affinity.c 
......................................................................................................................../Users/Neil/MASTERS/Isca/src/shared/mpp/affinity.c(35): error: identifier "__NR_gettid" is undefined 
eturn syscall(__NR_gettid); 
^ 
/Users/Neil/MASTERS/Isca/src/shared/mpp/affinity.c(44): error: identifier "cpu_set_t" is undefined 
cpu_set_t coremask;  /* core affinity mask */ 
^ 
/Users/Neil/MASTERS/Isca/src/shared/mpp/affinity.c(47): error: identifier "cpu_set_t" is undefined 
if (sched_getaffinity(gettid(),sizeof(cpu_set_t),&coremask) != 0) { 
^ 
/Users/Neil/MASTERS/Isca/src/shared/mpp/affinity.c(54): error: identifier "CPU_SETSIZE" is undefined 
for (cpu=0;cpu < CPU_SETSIZE;cpu++) { 
^ 
/Users/Neil/MASTERS/Isca/src/shared/mpp/affinity.c(75): error: identifier "cpu_set_t" is undefined 
cpu_set_t coremask;  /* core affinity mask */ 
^ 
/Users/Neil/MASTERS/Isca/src/shared/mpp/affinity.c(79): error: identifier "cpu_set_t" is undefined 
if (sched_setaffinity(gettid(),sizeof(cpu_set_t),&coremask) != 0) { 
^ 
compilation aborted for /Users/Neil/MASTERS/Isca/src/shared/mpp/affinity.c (code 2) 
make: *** [affinity.o] Error 2 
ERROR: mkmf failed for fms_moist 
CRITICAL - Compilation failed. 
Traceback (most recent call last): 
    File "run.py", line 25, in <module> 
    exp.compile() 
    File "/Users/Neil/MASTERS/Isca/src/extra/python/gfdl/experiment.py", line 298, in compile 
    raise e 
sh.ErrorReturnCode_1: 

    RAN: /bin/bash /Users/Neil/MASTERS/ISCA_TEMP/playground/compile.sh 

    STDOUT: 


    STDERR: 

Répondre

0

Votre googler vous mettre sur la bonne voie - sched_getaffinity() et la structure cpu_set_t qu'il utilise sont spécifiques à Linux et ne sont pas disponibles sur toutes les plateformes. Mac OSX en particulier semble les manquer.

Cependant, il existe des alternatives. J'ai trouvé a blog post from someone porting code to OSX qui a trouvé une alternative en utilisant sysctlbyname(). Le code sur ce site réimplémente sched_getaffinity() sur Mac OSX en demandant le machdep.cpu.core_count et en utilisant cela pour créer leur propre version de cpu_set_t.

+0

Merci d'avoir trouvé cet article. Juste une question rapide .. encore une fois parce que ma connaissance est assez basique. Une fois que j'ai "copié" leur version de cpu_set_t, comment l'utiliser? Comment puis-je faire en sorte que le script ci-dessus puisse y arriver? Merci. –

+0

@NeilLewis, juste pour clarifier, c'est une implémentation "fonctionne pour l'auteur" de l'API d'affinité Linux. Les indices d'affinité macOS ne sont que des indices. Il n'y a pas d'équivalent réel à la liaison/enfoncement de processus/fil dur que la plupart des autres systèmes d'exploitation (même Windows) fournissent. C'est un inconvénient majeur pour certaines applications hautes performances. J'ai vu des cas où la migration des threads augmente le temps d'exécution de plus de 50% sous Linux. –