2016-05-09 5 views
3

私は仮想マシンに1つのCPUソケットと16コアとコアあたり2つのスレッド(ハイパースレッディング)を持つGoogleクラウドを持っています。sched_getcpuは機能しません

これはlscpuの出力です:

Architecture:   x86_64 
CPU op-mode(s):  32-bit, 64-bit 
Byte Order:   Little Endian 
CPU(s):    32 
On-line CPU(s) list: 0-31 
Thread(s) per core: 2 
Core(s) per socket: 16 
Socket(s):    1 
NUMA node(s):   1 
Vendor ID:    GenuineIntel 
CPU family:   6 
Model:     63 
Stepping:    0 
CPU MHz:    2300.000 
BogoMIPS:    4600.00 
Hypervisor vendor:  KVM 
Virtualization type: full 
L1d cache:    32K 
L1i cache:    32K 
L2 cache:    256K 
L3 cache:    46080K 
NUMA node0 CPU(s):  0-31 

私はそれに私のプロセスを実行していると私は別の論理CPU間、私のスレッドを配布しようとしています。

unsigned num_cpus = std::thread::hardware_concurrency(); 
LOG(INFO) << "Going to assign threads to " << num_cpus << " logical cpus"; 
cpu_set_t cpuset; 
int rc = 0; 
for (int i = 0; i < num_cpus - 5; i++) { 
    worker_threads.push_back(std::thread(&CalculationWorker::work, &(workers[i]), i)); 
    // Create a cpu_set_t object representing a set of CPUs. Clear it and mark 
    // only CPU i as set. 
    CPU_ZERO(&cpuset); 
    CPU_SET(i, &cpuset); 
    int rc = pthread_setaffinity_np(worker_threads[i].native_handle(), 
      sizeof(cpu_set_t), &cpuset); 
    if (rc != 0) { 
     LOG(ERROR) << "Error calling pthread_setaffinity_np: " << rc << "\n"; 
    } 
    LOG(INFO) << "Set affinity for worker " << i << " to " << i; 
} 

事がnum_cpusが実際に32であるということですが、私は実行中のスレッドの一人一人に次のコード行を実行する場合:

LOG(INFO) << "Worker thread " << worker_number << " on CPU " << sched_getcpu(); 

sched_getcpu() 0を返すすべてのスレッドのために。
これは仮想マシンであるということと関係がありますか?

UPDATE:
私が利用している他のコアを見た理由です、バックグラウンドで実行されているいくつかのデーモンプロセスをSEREどうやらそこに、pthread_setaffinity_npが仕事をしていることが分かりました。
,sched_getcpuはまだ動作しませんし、すべてのスレッドで0を返しますが、別のコアで動作することははっきり分かります。

+0

'pthread_setaffinity_np()'の呼び出しが返った後、各スレッドの 'sched_getcpu()'への呼び出しが実行されていますか? – jotik

+0

@jotikまた、 'pthread_setaffinity_np'関数は実際に何もしません。すべてのスレッドのアフィニティを単一のコアに設定すると、スレッドはまだ別のコアで実行されています。 – eladm26

答えて

1

は、あなたの仮想マシン上でこの小さなプログラムを実行してみてくださいことができます:

#include <iostream> 
#include <thread> 
using namespace std; 

int main(int argc, char *argv[]) 
{ 
    int rc, i; 
    cpu_set_t cpuset; 
    pthread_t thread; 

    thread = pthread_self(); 

    //Check no. of cores on the machine 
    cout << thread::hardware_concurrency() << endl; 

    /* Set affinity mask */ 
    CPU_ZERO(&cpuset); 
    for (i = 0; i < 8; i++) //I have 4 cores with 2 threads per core so running it for 8 times, modify it according to your lscpu o/p 
     CPU_SET(i, &cpuset); 

    rc = pthread_setaffinity_np(thread, sizeof(cpu_set_t), &cpuset); 
    if (rc != 0) 
    cout << "Error calling pthread_setaffinity_np !!! "; 

    /* Assign affinity mask to the thread */ 
    rc = pthread_getaffinity_np(thread, sizeof(cpu_set_t), &cpuset); 
    if (rc != 0) 
    cout << "Error calling pthread_getaffinity_np !!!"; 

    cout << "pthread_getaffinity_np() returns:\n"; 
    for (i = 0; i < CPU_SETSIZE; i++) 
    { 
     if (CPU_ISSET(i, &cpuset)) 
      { 
      cout << " CPU " << i << endl; 
      cout << "This program (main thread) is on CPU " << sched_getcpu() << endl; 
     } 
    } 
    return 0; 
} 

pthread_setaffinity_npがVM上で作業されているかどうか。これはあなたのアイデアを与えるだろう。 VMの場合、そのような特定の制限はありません。代わりに、いくつかのプロセスでクラウド上のカーネルからのいくつかの強制が原因である可能性があります。あなたはそれについてもっと読むことができますhere

また、sched_setaffinity()を使用して、実際にVMでcpusetsを設定できるかどうかを確認してください。

私はすべてのスレッドのアフィニティを1つのコアに設定しても、スレッドは別のコアで実行されています)、元のポストのメモ(sched_getcpu()はすべてのスレッドに対して0を返します)おそらく、この0がすべてのスレッドのメインスレッド(プロセス)のために返されます。

+0

元の質問を更新したので、 'sched_setaffinity'は動作しますが、' sched_getcpu'はすべてのスレッドを0に戻し続けます。 – eladm26

関連する問題