利用C++多執行緒優化n王后問題

lt發表於2016-11-05

按照參考資料的寫法,與經典位運算結合,超過了單執行緒“世上最快”c程式.

#include <iostream>                // std::cout
#include <future>                // std::async, std::future, std::launch
#include <chrono>                // std::chrono::milliseconds
#include <thread>                // std::this_thread::sleep_for

#include <ctime>
int n = 12; 
int q(int i, int j, int k, int l) 
{ 
  int ans = 0;
  for(int a = ((1 << n) - 1) & ~(i | j | k), p = a & -a; a!=0; a ^= p, p = a & -a) 
  ans += q(i | p, (j | p) * 2, (k | p) / 2, l + 1);
  return l == n ? 1 : ans;
}
int main(int argc,char*argv[]) 
{ 
  int a=0;
  int t=clock();
  if (argc==2)
    n=atoi(argv[1]);
  a=q(0, 0, 0, 0);  
  printf("(normal)result of %d Q is %d,time is %d ms\n", n,a,clock()-t);

  a=0;
  t=clock();
  std::future < int >fb[20];
  for(int i=0;i<n;i++)
    fb[i]=std::async(std::launch::async, q,(1<<i),(1<<i)*2,(1<<i)/2,1);
  for(int i=0;i<n;i++)
    a+=fb[i].get();
  printf("(mthred)result of %d Q is %d,time is %d ms\n",n,a,clock()-t);

  a=0;
  t=clock();
  for(int i=0;i<n/2+(n%2);i++)
    fb[i]=std::async(std::launch::async, q,(1<<i),(1<<i)*2,(1<<i)/2,1);
  int b=0;
  if(n%2==1)
    b=fb[n/2+(n%2)-1].get();
  for(int i=0;i<n/2;i++)
    a+=fb[i].get();
  a=2*a+b;
  printf("(mthred+half)result of %d Q is %d,time is %d ms\n",n,a,clock()-t);

  return 0;
}

結果

D:\>cl mtq3.cpp -O2
用於 x86 的 Microsoft (R) C/C++ 優化編譯器 17.00.51106.1 版版權所有(C) Microsoft Corporation。保留所有權利。

mtq3.cpp
D:\vs2012\vc\bin\..\include\xlocale(336) : warning C4530: 使用了 C++ 異常處理程式,但未啟用展開語義。請指定 /EHsc
Microsoft (R) Incremental Linker Version 11.00.51106.1
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:mtq3.exe
mtq3.obj

D:\>mtq3
(normal)result of 12 Q is 14200,time is 15 ms
(mthred)result of 12 Q is 14200,time is 16 ms
(mthred+half)result of 12 Q is 14200,time is 0 ms

D:\>mtq3 15
(normal)result of 15 Q is 2279184,time is 3978 ms
(mthred)result of 15 Q is 2279184,time is 1606 ms
(mthred+half)result of 15 Q is 2279184,time is 858 ms

D:\>mtq3 16
(normal)result of 16 Q is 14772512,time is 26738 ms
(mthred)result of 16 Q is 14772512,time is 10327 ms
(mthred+half)result of 16 Q is 14772512,time is 5382 ms

D:\>timer nq 16
Timer 9.01 : Igor Pavlov : Public domain : 2009-05-31
N Queens program by Jeff Somers.
        allagash98@yahoo.com or jsomers@alumni.williams.edu
Start:   Sat Nov 05 11:00:37 2016
End:    Sat Nov 05 11:00:45 2016
Calculations took 8 seconds.
For board size 16, 14772512 solutions found.

Kernel Time  =     0.140 =    1%
User Time    =     8.548 =   97%
Process Time =     8.689 =   99%
Global Time  =     8.737 =  100%

D:\>timer nq 15
Timer 9.01 : Igor Pavlov : Public domain : 2009-05-31
N Queens program by Jeff Somers.
        allagash98@yahoo.com or jsomers@alumni.williams.edu
Start:   Sat Nov 05 11:02:35 2016
End:    Sat Nov 05 11:02:37 2016
Calculations took 2 seconds.
For board size 15, 2279184 solutions found.

Kernel Time  =     0.000 =    0%
User Time    =     1.357 =   95%
Process Time =     1.357 =   95%
Global Time  =     1.420 =  100%

相關文章