2010-04-01 14 views
16

(farklı CPU konu koymak) ve aşağıda benim kod çalıştırmasına zaman, vb Ancak, CPU 2, CPU 1 üzerinde çalışan iş parçacığının 1 ayarlamak için ipliği 2 çalışıyorum yakınlık maskeleri doğru değerleri döndürüyor, ancak iş parçacığı üzerinde bir sched_getcpu() yaptıkları zaman, hepsi CPU 4 üzerinde çalıştıklarını döndürüyorlar.CPU Affinity Maskeler ben 4 konuları var

Sorunumun ne olduğunu bilen var mı?

Şimdiden teşekkürler!

#define _GNU_SOURCE 
#include <stdio.h> 
#include <pthread.h> 
#include <stdlib.h> 
#include <sched.h> 
#include <errno.h> 

void *pthread_Message(char *message) 
{ 
    printf("%s is running on CPU %d\n", message, sched_getcpu()); 
} 

int main() 
{ 
    pthread_t thread1, thread2, thread3, thread4; 
    pthread_t threadArray[4]; 
    cpu_set_t cpu1, cpu2, cpu3, cpu4; 
    char *thread1Msg = "Thread 1"; 
    char *thread2Msg = "Thread 2"; 
    char *thread3Msg = "Thread 3"; 
    char *thread4Msg = "Thread 4"; 
    int thread1Create, thread2Create, thread3Create, thread4Create, i, temp; 

    CPU_ZERO(&cpu1); 
    CPU_SET(1, &cpu1); 
    temp = pthread_setaffinity_np(thread1, sizeof(cpu_set_t), &cpu1); 
    printf("Set returned by pthread_getaffinity_np() contained:\n"); 
    for (i = 0; i < CPU_SETSIZE; i++) 
     if (CPU_ISSET(i, &cpu1)) 
      printf("CPU1: CPU %d\n", i); 

    CPU_ZERO(&cpu2); 
    CPU_SET(2, &cpu2); 
    temp = pthread_setaffinity_np(thread2, sizeof(cpu_set_t), &cpu2); 
    for (i = 0; i < CPU_SETSIZE; i++) 
     if (CPU_ISSET(i, &cpu2)) 
      printf("CPU2: CPU %d\n", i); 

    CPU_ZERO(&cpu3); 
    CPU_SET(3, &cpu3); 
    temp = pthread_setaffinity_np(thread3, sizeof(cpu_set_t), &cpu3); 
    for (i = 0; i < CPU_SETSIZE; i++) 
     if (CPU_ISSET(i, &cpu3)) 
      printf("CPU3: CPU %d\n", i); 

    CPU_ZERO(&cpu4); 
    CPU_SET(4, &cpu4); 
    temp = pthread_setaffinity_np(thread4, sizeof(cpu_set_t), &cpu4); 
    for (i = 0; i < CPU_SETSIZE; i++) 
     if (CPU_ISSET(i, &cpu4)) 
      printf("CPU4: CPU %d\n", i); 

    thread1Create = pthread_create(&thread1, NULL, (void *)pthread_Message, thread1Msg); 
    thread2Create = pthread_create(&thread2, NULL, (void *)pthread_Message, thread2Msg); 
    thread3Create = pthread_create(&thread3, NULL, (void *)pthread_Message, thread3Msg); 
    thread4Create = pthread_create(&thread4, NULL, (void *)pthread_Message, thread4Msg); 

    pthread_join(thread1, NULL); 
    pthread_join(thread2, NULL); 
    pthread_join(thread3, NULL); 
    pthread_join(thread4, NULL); 

    return 0; 
} 

cevap

16

Başlamadığınız iş parçacıklarının yakınlığını ayarlamaya çalışıyorsunuz.

Düzenleme: Tamam, sana biraz daha bilgi verelim:

temsil ettikleri (eğer pthread_t değişkende saklamak şeyi) ve ne (bir yere çalışır yürütmenin parçacığı) iplik kolları karıştırmayın. Yapmaya çalıştığınız şey, iş parçacığı gerektiren bir API ile, başlamadan önce bir iş parçacığının özelliğini ayarlamaktır. o, pthread_create nesnesi yaratır ve aynı zamanda yürütme başlatır olur gibi öylesine pthread_setaffinity_np (bu değişim bir anda çalışan iş parçacığı benzeşme istiyorsanız yararlıdır) gitmek için doğru yol değildir kullanmaya çalışıyorum.

Ama ... pthread_create bir öznitelik parametre (buna BOŞ geçiyoruz) sahiptir. Bu, iş parçacığının nasıl oluşturulacağı bilgisini saklıyor.

Affinity bu parametreden ayarlayabilirsiniz niteliklerinden biridir. pthread_setaffinity_np(3): Ben en kolay Buradaki örnekte olduğu gibi her iş parçacığı için bir parametre olarak CPU maskesi vermek ve iplik talebi verilen yakınlık kendisi sahip olmak olacağını düşünüyorum tam olarak nasıl

+0

Bu yüzden pthread_create() onları önce mi kullanmalıyım? Ama bu zaten belirtilen işlevi çalıştırıyor ... Bu kavramın tamamını anladığımdan emin değilim. Bu yüzden benim pthread_Message() işlevimde setaffinity işlevini koymalı mıyım? – hahuang65

+0

İpliği çok * uzun * için çalıştırmanıza gerek yoktur, yani yeni oluşturulan parçanın yaptığı ilk şey olabilir. Bu yeni cpu maskesinin mevcut cpu içermemesi durumunda yeniden planlandığı anlamına gelir. – MarkR

+0

Hala anlamıyorum ... Ben() çağrıları veya pthread_create ÖNCE() pthread_create fonksiyonu SIRASINDA) pthread_create (SONRA benzeşim maskesini ayarlamak istediğiniz? – hahuang65

2

için pthread_attr_init ve pthread_attr_setaffinity_np için adam sayfalık belgelere bakın.

+0

Hangi ileti dizisini (benim durumumda, thread1, thread2, thread3 veya thread4) pthread_self() aradığını nasıl anlarım? – hahuang65

+0

Bence Bahbar zaten bunu yanıtladı - iş parçacığının kendisi için istediği yakınlık maskesini içeren bir yapıyı söyleyebilen, iş parçacığı işlev parametresini kullan. Aynı yapı örneğini çalışan iş parçacıkları arasında paylaşmamaya dikkat edin. –

4

Burada aradığını budur. Geç cevap olduğunu biliyorum, ama bu başkalarına yardımcı olabilir.

#include <stdio.h> 
#include <pthread.h> 
#include <stdlib.h> 
#include <sched.h> 
#include <errno.h> 

#include <unistd.h> 

int getNumberOfCpus(void) 
{ 
    long nprocs  = -1; 
    long nprocs_max = -1; 

    # ifdef _SC_NPROCESSORS_ONLN 
    nprocs = sysconf(_SC_NPROCESSORS_ONLN); 
    if (nprocs < 1) 
    { 
     //std::cout << "Could not determine number of CPUs on line. Error is " << strerror(errno) << std::endl; 
     return 0; 
    } 

    nprocs_max = sysconf(_SC_NPROCESSORS_CONF); 

    if (nprocs_max < 1) 
    { 
     //std::cout << "Could not determine number of CPUs in host. Error is " << strerror(errno) << std::endl; 
     return 0; 
    } 

    //std::cout << nprocs < " of " << nprocs_max << " online" << std::endl; 
    return nprocs; 

#else 
    //std::cout << "Could not determine number of CPUs" << std::endl; 
    return 0; 
#endif 
} 

void *pthread_Message(void *ptr) 
{ 
    sleep(10); 
    char *message; 
    message = (char *) ptr; 
    printf("%s \n", message); 
    cpu_set_t  l_cpuSet; 
    int   l_maxCpus; 
    int   j; 
    unsigned long l_cpuBitMask; 

    CPU_ZERO(&l_cpuSet); 
    printf("get affinity %d\n",pthread_getaffinity_np(pthread_self() , sizeof(cpu_set_t), &l_cpuSet)); 
    // printf("cpuset %d\n",l_cpuSet); 
    printf (" thread id %u\n", pthread_self());  

    if (pthread_getaffinity_np(pthread_self() , sizeof(cpu_set_t), &l_cpuSet) == 0) 
     for (int i = 0; i < 4; i++) 
      if (CPU_ISSET(i, &l_cpuSet)) 
       printf("XXXCPU: CPU %d\n", i); 
    for (long i=0; i< 10000000000; ++i); 
} 

int main() 
{ 
    pthread_t thread1, thread2, thread3, thread4; 
    pthread_t threadArray[4]; 
    cpu_set_t cpu1, cpu2, cpu3, cpu4; 
    const char *thread1Msg = "Thread 1"; 
    const char *thread2Msg = "Thread 2"; 
    const char *thread3Msg = "Thread 3"; 
    const char *thread4Msg = "Thread 4"; 
    int thread1Create, thread2Create, thread3Create, thread4Create, i, temp; 

    thread1Create = pthread_create(&thread1, NULL, &pthread_Message, (void*)thread1Msg); 
    sleep(1); 
    thread2Create = pthread_create(&thread2, NULL, &pthread_Message, (void*)thread2Msg); 
    sleep(1); 
    thread3Create = pthread_create(&thread3, NULL, &pthread_Message, (void*)thread3Msg); 
    sleep(1); 
    thread4Create = pthread_create(&thread4, NULL, &pthread_Message, (void*)thread4Msg); 


    CPU_ZERO(&cpu1); 
    CPU_SET(0, &cpu1); 
    temp = pthread_setaffinity_np(thread1, sizeof(cpu_set_t), &cpu1); 
    printf("setaffinity=%d\n", temp); 
    printf("Set returned by pthread_getaffinity_np() contained:\n"); 
    for (i = 0; i < CPU_SETSIZE; i++) 
     if (CPU_ISSET(i, &cpu1)) 
      printf("CPU1: CPU %d\n", i); 

    CPU_ZERO(&cpu2); 
    CPU_SET(1, &cpu2); 
    temp = pthread_setaffinity_np(thread2, sizeof(cpu_set_t), &cpu2); 
    for (i = 0; i < CPU_SETSIZE; i++) 
     if (CPU_ISSET(i, &cpu2)) 
      printf("CPU2: CPU %d\n", i); 

    CPU_ZERO(&cpu3); 
    CPU_SET(2, &cpu3); 
    temp = pthread_setaffinity_np(thread3, sizeof(cpu_set_t), &cpu3); 
    for (i = 0; i < CPU_SETSIZE; i++) 
     if (CPU_ISSET(i, &cpu3)) 
      printf("CPU3: CPU %d\n", i); 

    CPU_ZERO(&cpu4); 
    CPU_SET(3, &cpu4); 
    temp = pthread_setaffinity_np(thread4, sizeof(cpu_set_t), &cpu4); 
    for (i = 0; i < CPU_SETSIZE; i++) 
     if (CPU_ISSET(i, &cpu4)) 
      printf("CPU4: CPU %d\n", i); 

    // pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpu1); 



    // pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpu1); 

    pthread_join(thread1, NULL); 
    pthread_join(thread2, NULL); 
    pthread_join(thread3, NULL); 
    pthread_join(thread4, NULL); 

    return 0; 
}