- 追加された行はこのように表示されます。
- 削除された行は
このように表示されます。
!pthreadの実行時間計測
Linuxでpthreadの各スレッドの処理時間を
測定したいのだけど、どうしたらいいのかと尋ねられた。
普通に時間測定するならgetrusageだけど、
man pthreads
とかしてみると、
Posix.1のpthreadsで共有する属性の一つとして、CPU時間とリソース消費量が挙げられている。
NPTLでは、
- The information returned by times(2) and getrusage(2)
is per-thread rather than process-wide (fixed in kernel 2.6.9).
とあるので、やはり、getrusageではダメみたい。
実際やってみると、経過時間は、ちゃんと総和が得られているよう。
で、いろいろ調べてみると、pthread_getcpuclockidを使って
pthread_getcpuclockid(id, &c);
clock_gettime(c, &tp);
とすれば、各スレッドでの処理時間がとれるみたい。
ところで、FreeBSDのpthreadには、
pthread_getcpuclockidはないみたいだけど、
どうすればいいのかな?
ちなみに、Linuxでは、
man pthreads
FreeBSDでは、
man pthread
で、ちょっとびっくりした。
ちなみにテストしてみたソースコード
ちなみにテストしてみたソースコードは、次のようなもの。
コンパイルは、
gcc test.c -lpthread -lrt
とライブラリを指定する必要がある。
#include <stdio.h>
#include <sys/types.h>
#include <sys/time.h>
#include <time.h>
#include <sys/resource.h>
#include <pthread.h>
#define N 16
void print_rusage_usec(pthread_t id){
clockid_t c;
struct timespec tp;
struct timeval utime;
struct timeval stime;
pthread_getcpuclockid(id, &c);
clock_gettime(c, &tp);
printf("print_rusage_usec [%u] sec:%ld nsec:%ld\n",
id,
tp.tv_sec,
tp.tv_nsec
);
}
void *counter(void *arg)
{
volatile int i,j,k;
pid_t pid;
pthread_t thread_id;
pid = getpid();
thread_id = pthread_self();
print_rusage_usec(thread_id);
for(i = 0; i < 1000; i++){
for(j = 0; j < 1000; j++){
for(k = 0; k < 1000; k++){
}
}
}
print_rusage_usec(thread_id);
return(arg);
}
int main()
{
int status;
void *result;
pthread_t thread_id[N];
int i;
struct timespec tp;
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tp);
printf("process sec:%ld nsec:%ld\n", tp.tv_sec, tp.tv_nsec);
for(i = 0; i < N; i++){
status = pthread_create(&thread_id[i], NULL, counter, (void *)NULL);
if(status != 0){
fprintf(stderr, "pthread_create : %s", strerror(status));
}
else{
//printf("thread %d is createed\n", thread_id[i]);
}
}
for(i = 0; i < N; i++){
pthread_join(thread_id[i], &result);
//printf("thread %d is ended\n", thread_id[i]);
}
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tp);
printf("process sec:%ld nsec:%ld\n", tp.tv_sec, tp.tv_nsec);
}