Actual source code: sseenabled.c
1: /* $Id: sseenabled.c,v 1.15 2001/07/20 21:03:24 buschelm Exp $ */
2: #include petscsys.h
4: #ifdef PETSC_HAVE_SSE
6: #include PETSC_HAVE_SSE
7: #define SSE_FEATURE_FLAG 0x2000000 /* Mask for bit 25 (from bit 0) */
9: #include <string.h>
11: int PetscSSEHardwareTest(PetscTruth *flag) {
12: int ierr;
13: char *vendor;
14: char Intel[13]="GenuineIntel";
15: char AMD[13] ="AuthenticAMD";
18: PetscMalloc(13*sizeof(char),&vendor);
19: strcpy(vendor,"************");
20: CPUID_GET_VENDOR(vendor);
21: if (!strcmp(vendor,Intel) || !strcmp(vendor,AMD)) {
22: /* Both Intel and AMD use bit 25 of CPUID_FEATURES */
23: /* to denote availability of SSE Support */
24: unsigned long myeax,myebx,myecx,myedx;
25: CPUID(CPUID_FEATURES,&myeax,&myebx,&myecx,&myedx);
26: if (myedx & SSE_FEATURE_FLAG) {
27: *flag = PETSC_TRUE;
28: } else {
29: *flag = PETSC_FALSE;
30: }
31: }
32: PetscFree(vendor);
33: return(0);
34: }
36: #ifdef PARCH_linux
37: #include <signal.h>
38: /*
39: Early versions of the Linux kernel disables SSE hardware because
40: it does not know how to preserve the SSE state at a context switch.
41: To detect this feature, try an sse instruction in another process.
42: If it works, great! If not, an illegal instruction signal will be thrown,
43: so catch it and return an error code.
44: */
45: #define PetscSSEOSEnabledTest(arg) PetscSSEOSEnabledTest_Linux(arg)
47: static void PetscSSEDisabledHandler(int sig) {
48: signal(SIGILL,SIG_IGN);
49: exit(-1);
50: }
52: int PetscSSEOSEnabledTest_Linux(PetscTruth *flag) {
53: int status, pid = 0;
55: signal(SIGILL,PetscSSEDisabledHandler);
56: pid = fork();
57: if (pid==0) {
58: SSE_SCOPE_BEGIN;
59: XOR_PS(XMM0,XMM0);
60: SSE_SCOPE_END;
61: exit(0);
62: } else {
63: wait(&status);
64: }
65: if (!status) {
66: *flag = PETSC_TRUE;
67: } else {
68: *flag = PETSC_FALSE;
69: }
70: return(0);
71: }
73: #endif
74: #ifdef PARCH_win32
75: /*
76: Windows 95/98/NT4 should have a Windows Update/Service Patch which enables this hardware.
77: Windows ME/2000 doesn't disable SSE Hardware
78: */
79: #define PetscSSEOSEnabledTest(arg) PetscSSEOSEnabledTest_TRUE(arg)
81: int PetscSSEOSEnabledTest_TRUE(PetscTruth *flag) {
83: *flag = PETSC_TRUE;
84: return(0);
85: }
87: #endif
88: #else /* Not defined PETSC_HAVE_SSE */
90: #define PetscSSEHardwareTest(arg) 0
91: #define PetscSSEOSEnabledTest(arg) 0
93: #endif /* defined PETSC_HAVE_SSE */
95: /*@C
96: PetscSSEIsEnabled - Determines if Intel Streaming SIMD Extensions to the x86 instruction
97: set can be used. Some operating systems do not allow the use of these instructions despite
98: hardware availability.
100: Collective on MPI_Comm
102: Input Parameter:
103: . comm - the MPI Communicator
105: Output Parameters:
106: . lflag - Local Flag: PETSC_TRUE if enabled in this process
107: . gflag - Global Flag: PETSC_TRUE if enabled for all processes in comm
109: Level: developer
110: @*/
111: int PetscSSEIsEnabled(MPI_Comm comm,PetscTruth *lflag,PetscTruth *gflag) {
114: *lflag = PETSC_FALSE;
115: *gflag = PETSC_FALSE;
116: PetscSSEHardwareTest(lflag);
117: if (*lflag) {
118: PetscSSEOSEnabledTest(lflag);
119: }
120: MPI_Allreduce(gflag,lflag,1,MPI_INT,MPI_LAND,comm);
121: return(0);
122: }