第18講 マルチスレッドプログラミング=並列処理プログラミング

第8話 第3番目の引数を利用して関数を1本化する

プログラム改良例

#include<iostream>
#include<process.h>
#include<math.h>
using namespace std;
void f(void *a);
char sh(int i);
int t1,t2,t3,t4,t5,t6;
int cn1,cn2,cn3,cn4,cn5,cn6;
long s1[10000000],s2[10000000],s3[10000000],s4[10000000],s5[10000000],s6[10000000];
void main(){
   t1=0;
   t2=0;
   t3=0;
   t4=0;
   t5=0;
   t6=0;
   _beginthread(f,0,(void *)1); //新しいスレッドを起動して、そのスレッド上で関数fを働かせなさいの命令
   _beginthread(f,0,(void *)2); //新しいスレッドを起動して、そのスレッド上で関数fを働かせなさいの命令
   _beginthread(f,0,(void *)3); //新しいスレッドを起動して、そのスレッド上で関数fを働かせなさいの命令
   _beginthread(f,0,(void *)4); //新しいスレッドを起動して、そのスレッド上で関数fを働かせなさいの命令
   _beginthread(f,0,(void *)5); //新しいスレッドを起動して、そのスレッド上で関数fを働かせなさいの命令
   _beginthread(f,0,(void *)6); //新しいスレッドを起動して、そのスレッド上で関数fを働かせなさいの命令
   while (t1*t2*t3*t4*t5*t6==0);
   int i;
   int i;
   cout<<"7で割ると1余る素数"<<endl;
   for(i=0;i<cn1;i++){
     cout<<s1[i]<<" ";
     if(i>0 && i%10==0)cout<<endl;
   }
   cout<<endl;
   cout<<"7で割ると2余る素数"<<endl;
   for(i=0;i<cn2;i++){
     cout<<s2[i]<<" ";
     if(i>0 && i%10==0)cout<<endl;
   }
   cout<<endl;
   cout<<"7で割ると3余る素数"<<endl;
   for(i=0;i<cn3;i++){
     cout<<s3[i]<<" ";
     if(i>0 && i%10==0)cout<<endl;
   }
   cout<<endl;
   cout<<"7で割ると4余る素数"<<endl;
   for(i=0;i<cn4;i++){
     cout<<s4[i]<<" ";
     if(i>0 && i%10==0)cout<<endl;
   }
   cout<<endl;
   cout<<"7で割ると5余る素数"<<endl;
   for(i=0;i<cn5;i++){
     cout<<s5[i]<<" ";
     if(i>0 && i%10==0)cout<<endl;
   }
   cout<<endl;
   cout<<"7で割ると6余る素数"<<endl;
   for(i=0;i<cn6;i++){
     cout<<s6[i]<<" ";
     if(i>0 && i%10==0)cout<<endl;
   }
}
void f(void *a){
   if(a==(void *)1){
     cn1=0;
     for(int i=29;i<1001;i+=14){
        if(sh(i)){
          s1[cn1]=i;
          cn1++;
        }
     }
     t1=1;
   }
   if(a==(void *)2){
     s2[0]=2;
     cn2=1;
     for(int i=23;i<1001;i+=14){
        if(sh(i)){
           s2[cn2]=i;
           cn2++;
        }
     }
     t2=1;
   }
   if(a==(void *)3){
     cn3=0;
     for(int i=3;i<1001;i+=14){
        if(sh(i)){
          s3[cn3]=i;
          cn3++;
        }
     }
     t3=1;
   }
   if(a==(void *)4){
     cn4=0;
     for(int i=11;i<1001;i+=14){
        if(sh(i)){
          s4[cn4]=i;
          cn4++;
        }
     }
     t4=1;
   }
   if(a==(void *)5){
     cn5=0;
     for(int i=5;i<1001;i+=14){
        if(sh(i)){
          s5[cn5]=i;
          cn5++;
        }
     }
     t5=1;
   }
   if(a==(void *)6){
     cn6=0;
     for(int i=13;i<1001;i+=14){
        if(sh(i)){
          s6[cn6]=i;
          cn6++;
        }
     }
     t6=1;
   }
}
char sh(int g){
   if(g==1)return(0);
   if(g==2)return(1);
   if(g==3)return(1);
   if(g>0 && g%2==0)return(0);
   for(int i=3;i<=sqrt((double)g);i+=2)if(g%i==0)return(0);
   return(1);
}
参考ダウンロード添付ファイル

ところで、7スレッドと書いてあるけど、
本当は6スレッドプログラミングでは???
と思い方もいらっしゃったと思います。
でも、タイピングミスではないんですよ。
   _beginthread(f,0,(void *)1); //新しいスレッドを起動して、そのスレッド上で関数fを働かせなさいの命令
   _beginthread(f,0,(void *)2); //新しいスレッドを起動して、そのスレッド上で関数fを働かせなさいの命令
   _beginthread(f,0,(void *)3); //新しいスレッドを起動して、そのスレッド上で関数fを働かせなさいの命令
   _beginthread(f,0,(void *)4); //新しいスレッドを起動して、そのスレッド上で関数fを働かせなさいの命令
   _beginthread(f,0,(void *)5); //新しいスレッドを起動して、そのスレッド上で関数fを働かせなさいの命令
   _beginthread(f,0,(void *)6); //新しいスレッドを起動して、そのスレッド上で関数fを働かせなさいの命令
なのにどうして?
ルートスレッドが働いていることをお忘れですよ。
ただ、このプログラムでは
   while (t1*t2*t3*t4*t5*t6==0);
で派生スレッドの仕事が終わるまで、待機しているだけですから、
ルートスレッドが無駄にはなっています。
そこを改良しても良いのですが、
CPU使用率が100%になったことに満足して、
講を改めることにします。
第19講では座標を工夫し、
魔方陣自動生成ソフトの高速化を図り、
第20講では末項確定法により、さらなる高速化を図り、
第2?講ではさらに、マルチスレッド化します。
この3つの工夫によって、
魔方陣自動生成ソフトは、
数万倍も高速化します。
それに、よって6次魔方陣当たりまでが作成できるようになります。
さらに、将来の講で特殊種法・一般種法・細胞構成法等を学ぶと、
数億倍から数京(京は超の1万倍)倍の高速化を実現し、
26次魔方陣当たりでも、
1秒で数百の単位で生成できるようになります。

第18講を終了させる前に1つだけ、
説明しておきたいと思います。
それは、
   while (t1*t2*t3*t4*t5*t6==0);
です。第7話までは、t1からt6は1に初期化されていましたが、
今回は0で初期化されていました。
ですから、while文を抜け出すためには、
t1からt6のすべてが1にならないといけないわけです。
   while (t1*t2*t3*t4*t5*t6==0);
はもちろん
   while (t1==0 || t2==0 || t3==0 || t4==0 || t5==0);
でも良いわけですが、
かけ算は1個でも0だと0になることを利用する
   while (t1*t2*t3*t4*t5*t6==0);
という方法を是非とも覚えて下さい。


第7話へ 第19講第1話へ

a

eclipse c++ 入門講義第1部へ

魔方陣 数独で学ぶ VBA 入門
数独のシンプルな解き方・簡単な解法の研究
VB講義へ
VB講義基礎へ
初心者のための世界で一番わかりやすいVisual C++入門基礎講座
初心者のための世界で一番わかりやすいVisual Basic入門基礎講座
初心者のための世界で一番わかりやすいVBA入門講義(基礎から応用まで)
初心者のための VC++による C言語 C++ 入門 基礎から応用まで第1部
eclipse java 入門
java 入門 サイト 基礎から応用まで
VC++ C言語 C++ 入門 初心者 基礎から応用まで
本サイトトップへ