2015年1月13日火曜日

開発環境

Head First C ―頭とからだで覚えるCの基本(David Griffiths (著)、Dawn Griffiths (著) 中田 秀基(監訳)(翻訳)、木下 哲也 (翻訳)、オライリージャパン)の12章(スレッド: 並列の世界)、長いエクササイズ(p.516)を解いてみる。

その他参考書籍

長いエクササイズ(p.516)

バージョンAは1つ目、バージョンBは2つ目に対応する。

コード(BBEdit, Emacs)

sample516_a.c

#include <stdio.h>
#include <pthread.h>

int beers = 2000000;

pthread_mutex_t beers_lock = PTHREAD_MUTEX_INITIALIZER;
void* drink_lots(void *a){
  pthread_mutex_lock(&beers_lock);
  for (int i = 0; i < 100000; i++) beers--;
  pthread_mutex_unlock(&beers_lock);
  printf("beers = %i\n", beers);
  return NULL;
}

int main() {
  pthread_t threads[20];
  printf("壁にはビールが%i本\n%i本のビール\n", beers, beers);
  for (int t = 0; t < 20; t++)
    pthread_create(&threads[t], NULL, drink_lots, NULL);
  void *result;
  for (int t = 0; t < 20; t++)
    pthread_join(threads[t], &result);
  printf("現在、壁にはビールが%i本あります\n", beers);
}

sample516_b.c

#include <stdio.h>
#include <pthread.h>

int beers = 2000000;

pthread_mutex_t beers_lock = PTHREAD_MUTEX_INITIALIZER;
void* drink_lots(void *a){
  for (int i = 0; i < 100000; i++){
    pthread_mutex_lock(&beers_lock);
    beers--;
    pthread_mutex_unlock(&beers_lock);
  }
  printf("beers = %i\n", beers);
  return NULL;
}

int main() {
  pthread_t threads[20];
  printf("壁にはビールが%i本\n%i本のビール\n", beers, beers);
  for (int t = 0; t < 20; t++)
    pthread_create(&threads[t], NULL, drink_lots, NULL);
  void *result;
  for (int t = 0; t < 20; t++)
    pthread_join(threads[t], &result);
  printf("現在、壁にはビールが%i本あります\n", beers);
}

OpenMPを使った場合。

sample516_openmp.c

#include <stdio.h>

int main() {
  int beers = 2000000;
  printf("壁にはビールが%i本\n%i本のビール\n", beers, beers);
  
  #pragma omp parallel for reduction(-:beers)
  for (int t = 0; t < 20; t++) {
    beers -= 100000;
    printf("beers = %i\n", beers);
  }
  printf("現在、壁にはビールが%i本あります\n", beers);
}

入出力結果(Terminal)

$ crun.sh sample516_a
clang ...
壁にはビールが2000000本
2000000本のビール
beers = 1900000
beers = 1800000
beers = 1700000
beers = 1600000
beers = 1500000
beers = 1400000
beers = 1300000
beers = 1200000
beers = 1100000
beers = 1000000
beers = 900000
beers = 800000
beers = 700000
beers = 600000
beers = 500000
beers = 400000
beers = 300000
beers = 200000
beers = 100000
beers = 0
現在、壁にはビールが0本あります
$ crun.sh sample516_b
clang ...
壁にはビールが2000000本
2000000本のビール
beers = 13398
beers = 25
beers = 20
beers = 18
beers = 16
beers = 15
beers = 14
beers = 13
beers = 12
beers = 11
beers = 10
beers = 9
beers = 8
beers = 7
beers = 6
beers = 5
beers = 3
beers = 2
beers = 1
beers = 0
現在、壁にはビールが0本あります
$ crun.sh sample516_openmp
gcc ...
壁にはビールが2000000本
2000000本のビール
beers = -100000
beers = -100000
beers = -200000
beers = -100000
beers = -100000
beers = -200000
beers = -300000
beers = -200000
beers = -200000
beers = -300000
beers = -400000
beers = -300000
beers = -300000
beers = -400000
beers = -500000
beers = -400000
beers = -400000
beers = -500000
beers = -500000
beers = -500000
現在、壁にはビールが0本あります
$ ./sample516_openmp
壁にはビールが2000000本
2000000本のビール
beers = -100000
beers = -200000
beers = -300000
beers = -400000
beers = -500000
beers = -100000
beers = -200000
beers = -300000
beers = -400000
beers = -500000
beers = -100000
beers = -200000
beers = -300000
beers = -400000
beers = -500000
beers = -100000
beers = -200000
beers = -300000
beers = -400000
beers = -500000
現在、壁にはビールが0本あります
$

0 コメント:

コメントを投稿