第22講 素数探索を題材としたマルチスレッドプログラミングの学習
第7話 スレッド6の解答例
スレッド6の解答例
#pragma once
#include <math.h>
#include<stdlib.h>
#include<set>
using namespace std;
int N;
int cn1,cn2,cn3,cn4,cn5,cn6;
int s1[25000000],s2[25000000],s3[25000000],s4[25000000],s5[25000000],s6[25000000];
namespace 素数探索6スレッド {
・
・
・
#pragma endregion
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^
e) {
set<int> s;
int i,j,cn;
N=int::Parse(textBox1->Text);
s.clear();
s.insert(2);s.insert(3);s.insert(5);s.insert(7);
for(i=0;i<cn1;i++){
s1[i]=0;
cn1=0;
}
for(i=0;i<cn2;i++){
s2[i]=0;
cn2=0;
}
for(i=0;i<cn3;i++){
s3[i]=0;
cn3=0;
}
for(i=0;i<cn4;i++){
s4[i]=0;
cn4=0;
}
for(i=0;i<cn5;i++){
s5[i]=0;
cn5=0;
}
for(i=0;i<cn6;i++){
s6[i]=0;
cn6=0;
}
DateTime^ hj=DateTime::Now; //開始時間
//スレッドの生成
Thread^ A=gcnew Thread(gcnew ThreadStart(f1));
Thread^ B=gcnew Thread(gcnew ThreadStart(f2));
Thread^ C=gcnew Thread(gcnew ThreadStart(f3));
Thread^ D=gcnew Thread(gcnew ThreadStart(f4));
Thread^ E=gcnew Thread(gcnew ThreadStart(f5));
Thread^ F=gcnew Thread(gcnew ThreadStart(f6));
//計算開始
A->Start();
B->Start();
C->Start();
D->Start();
E->Start();
F->Start();
//スレッドの終了を待つ
A->Join();
B->Join();
C->Join();
D->Join();
E->Join();
F->Join();
array<String^>^ w=gcnew array<String^>(10);
DateTime^ ow=DateTime::Now; //終了時間
for(i=0;i<=cn1;i++){
s.insert(s1[i]);
}
for(i=0;i<=cn2;i++){
s.insert(s2[i]);
}
for(i=0;i<=cn3;i++){
s.insert(s3[i]);
}
for(i=0;i<=cn4;i++){
s.insert(s4[i]);
}
for(i=0;i<=cn5;i++){
s.insert(s5[i]);
}
for(i=0;i<=cn6;i++){
s.insert(s6[i]);
}
cn=0;
for(set<int>::iterator it=s.begin();it!=s.end();it++){
if(*it==0)it++;
w[cn%10]=(*it).ToString();
if(cn==cn1+cn2+cn3+cn4+cn5+cn6+3){
for(j=(cn%10)+1;j<10;j++){
w[j]=L"";
}
}
if(cn%10==9)dataGridView1->Rows->Add(w);
cn++;
}
dataGridView1->Rows->Add(w);
TimeSpan sa=ow->Subtract(*hj); //経過時間の計算
w[0]=L"計算時間"; w[1]=sa.TotalSeconds.ToString();
for(i=2;i<10;i++)w[i]=L"";
dataGridView1->Rows->Add(w);
w[0]=L"素数個数"; w[1]=(cn1+cn2+cn3+cn4+cn5+cn6+4).ToString();
dataGridView1->Rows->Add(w);
}
static void f1(){
for (int i=8; i<=N; i+=7) {
if(sh(i)){
s1[cn1]=i;
cn1++;
}
}
}
static void f2(){
for (int i=9; i<=N; i+=7) {
if(sh(i)){
s2[cn2]=i;
cn2++;
}
}
}
static void f3(){
for (int i=10; i<=N; i+=7) {
if(sh(i)){
s3[cn3]=i;
cn3++;
}
}
}
static void f4(){
for (int i=11; i<=N; i+=7) {
if(sh(i)){
s4[cn4]=i;
cn4++;
}
}
}
static void f5(){
for (int i=12; i<=N; i+=7) {
if(sh(i)){
s5[cn5]=i;
cn5++;
}
}
}
static void f6(){
for (int i=13; i<=N; i+=7) {
if(sh(i)){
s6[cn6]=i;
cn6++;
}
}
}
static char sh(double n){
char h=1;
double a;
int b;
int c;
int i;
a=sqrt(n);
b=(int)a;
c=(int)n;
if(c % 2==0)h=0;
if(h==1){
for(i=3;i<=a;i=i+2){
if(c % i==0){
h=0;
break;
}
}
}
return(h);
}
};
}
ダウンロード用ファイルForm11.h
実験結果
探索範囲 | 10000 | 100000 | 1000000 | 10000000 |
4スレッド | 0.0156 | 0.0312 | 0.159 | 2.418 |
6スレッド | 0.0624 | 0.0468 | 0.2964 | 2.6208 |
倍数差 | 4 | 1.5 | 1.864150943 | 1.083870968 |
残念ながら、4スレッドの方が速いようです。
私のパソコン4CPUなので、当然かもしれませんね。
将来、8CPUが普通になるといわれていますから、今回作った6スレッドもそのときには生かされるでしょう。
今回の6スレッドにしても、前回の4スレッドにしても素数を作る各関数は
static void f1(){
for (int i=8; i<=N; i+=7) {
if(sh(i)){
s1[cn1]=i;
cn1++;
}
}
}
static void f2(){
for (int i=9; i<=N; i+=7) {
if(sh(i)){
s2[cn2]=i;
cn2++;
}
}
}
static void f3(){
for (int i=10; i<=N; i+=7) {
if(sh(i)){
s3[cn3]=i;
cn3++;
}
}
}
・
・
・
ほぼ同一の構造をもっています。
そこで、次話ではThreadStartの代わりにParameterizedThreadStartを使い、
4つないし6つの関数を1つの関数にまとめます。
第22講第6話へ 第22講第8話へ
VC++講義第1部へ
vb講義へ
VB講義基礎へ
初心者のための世界で一番わかりやすいVisual C++入門基礎講座
初心者のための世界で一番わかりやすいVisual
Basic入門基礎講座