Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 这是测量线程上下文切换开销的正确解决方案吗?_C_Multithreading_Pthreads_Context Switch - Fatal编程技术网

C 这是测量线程上下文切换开销的正确解决方案吗?

C 这是测量线程上下文切换开销的正确解决方案吗?,c,multithreading,pthreads,context-switch,C,Multithreading,Pthreads,Context Switch,我试图测量线程切换开销时间。 我有两个线程、一个共享变量、一个互斥锁和两个条件变量。两个线程将来回切换,将1或0写入共享变量 我假设pthread_cond_wait(&cond,&mutex)等待时间大约等于2倍线程上下文切换时间。因为如果thread1必须等待条件变量,它必须将互斥锁放弃给thread2->thread2上下文开关,thread2执行其任务并向条件变量发送信号以唤醒第一个线程 ->上下文切换回thread1->thread1重新获取锁 我的假设正确吗 我的代码如下: #inc

我试图测量线程切换开销时间。 我有两个线程、一个共享变量、一个互斥锁和两个条件变量。两个线程将来回切换,将1或0写入共享变量

我假设pthread_cond_wait(&cond,&mutex)等待时间大约等于2倍线程上下文切换时间。因为如果thread1必须等待条件变量,它必须将互斥锁放弃给thread2->thread2上下文开关,thread2执行其任务并向条件变量发送信号以唤醒第一个线程 ->上下文切换回thread1->thread1重新获取锁

我的假设正确吗

我的代码如下:

#include <sys/types.h>
#include <wait.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/resource.h>
#include <dirent.h>
#include <ctype.h>
#include<signal.h>
#include <stdio.h>
#include <stdint.h>
#include <time.h>
#include <pthread.h>


int var = 0;

int setToZero = 1;

int count = 5000;

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

pthread_cond_t isZero = PTHREAD_COND_INITIALIZER;

pthread_cond_t isOne = PTHREAD_COND_INITIALIZER;


struct timespec firstStart; 

unsigned long long timespecDiff(struct timespec *timeA_p, struct timespec *timeB_p)
{
  return ((timeA_p->tv_sec * 1000000000) + timeA_p->tv_nsec) - 
           ((timeB_p->tv_sec * 1000000000) + timeB_p->tv_nsec);
}

void* thread1(void* param)
{ 

  int rc;
  struct timespec previousStart;
  struct timespec start; //start timestamp
  struct timespec stop; //stop timestamp
  unsigned long long result;
  int idx = 0;
  int measurements[count];
   clock_gettime(CLOCK_MONOTONIC, &stop);

   result = timespecDiff(&stop,&firstStart);

   printf("first context-switch time:%llu\n", result);

  clock_gettime(CLOCK_MONOTONIC, &previousStart);

  while(count > 0){

  //acquire lock
  rc = pthread_mutex_lock(&mutex);

  clock_gettime(CLOCK_MONOTONIC,&start);

  while(setToZero){
    pthread_cond_wait(&isOne,&mutex); // use condition variables so the threads don't busy wait inside local cache
  }

  clock_gettime(CLOCK_MONOTONIC,&stop);


   var = 0;

   count--;

   setToZero = 1;

   //printf("in thread1\n");

   pthread_cond_signal(&isZero);
    //end of critical section
   rc = pthread_mutex_unlock(&mutex); //release lock

    result = timespecDiff(&stop,&start);

    measurements[idx] = result;

    idx++;
 }

 result = 0;

 int i = 0;
while(i < idx)
 {
   result += measurements[i++];
 }

 result = result /(2*idx);

 printf("thread1 result: %llu\n",result);
}


void* thread2(void* param)
{
  int rc;
  struct timespec previousStart;
  struct timespec start; //start timestamp
  struct timespec stop; //stop timestamp
  unsigned long long result;
  int idx = 0;
  int measurements[count];

  while(count > 0){

  //acquire lock
  rc = pthread_mutex_lock(&mutex);

  clock_gettime(CLOCK_MONOTONIC,&start);

  while(!setToZero){
    pthread_cond_wait(&isZero,&mutex);
  }

  clock_gettime(CLOCK_MONOTONIC,&stop);

   var = 1;

   count--;

   setToZero = 0;

   //printf("in thread2\n");

   pthread_cond_signal(&isOne);
    //end of critical section
   rc = pthread_mutex_unlock(&mutex); //release lock

   result = timespecDiff(&stop,&start);

   measurements[idx] = result;

   idx++;
  }

 result = 0;

 int i = 0;
while(i < idx)
 {
   result += measurements[i++];
 }

 result = result /(2*idx);

 printf("thread2 result: %llu\n",result);
}

int main(){
  pthread_t threads[2];

  pthread_attr_t attr;

  pthread_attr_init(&attr);

  clock_gettime(CLOCK_MONOTONIC,&firstStart);

  pthread_create(&threads[0],&attr,thread1,NULL);

  pthread_create(&threads[1],&attr,thread2,NULL);

  printf("waiting...\n");

  pthread_join(threads[0],NULL);

  pthread_join(threads[1],NULL);

  pthread_cond_destroy(&isOne);

  pthread_cond_destroy(&isZero);

}
你说:

我假设pthread_cond_wait(&cond,&mutex)等待时间大约等于2倍线程上下文切换时间

这不是一个有效的假设。一旦释放互斥锁,就会通知内核,然后内核必须唤醒另一个线程。它可能不会选择立即这样做,例如,如果有其他线程等待运行。互斥锁——顾名思义——保证事情不会发生。它不能保证他们什么时候会这样做

您不能期望从流程中可靠地度量上下文切换,当然也不能使用POSIXAPI,因为没有任何一个API承诺能够做到这一点

  • 在Linux上,您可以使用
    /proc/[pid]/status
    计算进程或线程的上下文切换

  • 在Windows上,此信息可从性能监视器API获得

我不知道这两者是否能让你朝着目标前进。我想您真正想知道的是使用多线程系统对性能的影响,但这需要您衡量整个应用程序的性能。

您说:

我假设pthread_cond_wait(&cond,&mutex)等待时间大约等于2倍线程上下文切换时间

这不是一个有效的假设。一旦释放互斥锁,就会通知内核,然后内核必须唤醒另一个线程。它可能不会选择立即这样做,例如,如果有其他线程等待运行。互斥锁——顾名思义——保证事情不会发生。它不能保证他们什么时候会这样做

您不能期望从流程中可靠地度量上下文切换,当然也不能使用POSIXAPI,因为没有任何一个API承诺能够做到这一点

  • 在Linux上,您可以使用
    /proc/[pid]/status
    计算进程或线程的上下文切换

  • 在Windows上,此信息可从性能监视器API获得


我不知道这两者是否能让你朝着目标前进。我想您真正想知道的是,使用多线程系统对性能的影响有多大,但这需要您衡量整个应用程序的性能。

除非您只有一个CPU内核,在这种情况下,线程可能根本不需要进行上下文切换。我使用的是单核机器,而且还有其他进程/线程需要cpu时间。上下文切换是状态变量等的加载/卸载,我认为你无法测量它,你甚至可能会受到观察者效应的影响:)操作系统是由上下文切换负责的,在用户空间中,你无法控制它,这一切都发生在进程睡眠时。@selcuk Cihan:我认为这不一定是真的。关于这个主题还有其他的SO帖子:除非你只有一个CPU内核,否则在这种情况下,线程可能根本不需要进行上下文切换。我使用的是一台单核机器,而且还有其他进程/线程需要CPU时间。上下文切换是状态变量等的加载/卸载,我认为你无法测量它,你甚至可能会受到观察者效应的影响:)操作系统是由上下文切换负责的,在用户空间中,你无法控制它,这一切都发生在进程睡眠时。@selcuk Cihan:我认为这不一定是真的。关于此主题,还有其他SO帖子:
first context-switch time:144240
thread1 result: 3660
thread2 result: 3770