我是否错误地使用了Win API函数InterlockedIncrement
或C ++?
我编写了一个并行程序,使用Win API查找从1到N的素数。我使用了InterlockedIncrement
,但仍然得到错误的答案。这是我的代码:
#include <iostream>
#include <windows.h>
#include <process.h>
#include <vector>
#include <ctime>
#include <cmath>
using namespace std;
typedef unsigned long long element_t;
typedef element_t count_t;
count_t count;
element_t N;
const int BATCH_SIZE = (1 << 20) - 1;
bool prime(element_t n) {
if (n < 2) {
return false;
}
for (element_t i = 2, end = (element_t) sqrt(n) + 1; i < end; i++) {
if (n % i == 0) {
return false;
}
}
return true;
}
struct arg_list_t {
element_t from;
element_t to;
arg_list_t(element_t f, element_t t)
: from(f), to(t) { }
};
unsigned int WINAPI thread_func(void *params) {
arg_list_t *arg_list = static_cast<arg_list_t *>(params);
element_t from = arg_list->from, to = arg_list->to;
for (element_t i = from; i < to; i++) {
if (prime(i)) {
InterlockedIncrement(&count);
}
}
_endthreadex(0);
return 0;
}
int main(void) {
cout << "Enter the value of N: ";
cin >> N;
vector<arg_list_t> arg_lists;
vector<HANDLE> handles;
vector<unsigned int> thread_ids;
cout << "Windows API" << endl;
cout << "[INFO] Calculating ..." << endl;
clock_t start = clock();
element_t from = 2, to = min(N, from + BATCH_SIZE) + 1;
while (from < N) {
unsigned int thread_id;
arg_lists.push_back({from, to});
handles.push_back((HANDLE) _beginthreadex(
NULL, 0, thread_func, (void *) &arg_lists.back(), 0, &thread_id));
thread_ids.push_back(thread_id);
from = to;
to = min(N, from + BATCH_SIZE) + 1;
}
WaitForMultipleObjects(handles.size(), &handles[0], TRUE, INFINITE);
clock_t end = clock();
cout << "[INFO] Done! Total time: "
<< static_cast<double>(end - start) / CLOCKS_PER_SEC
<< " second(s)" << endl;
cout << "There are " << count
<< " prime(s) in the range [1, " << N << "]" << endl;
return 0;
}
例如,如果我将N
设置为10,000,000,则串行程序会给出(正确的)答案664579
,但是上面的程序会给出诸如300386
,{{1} }。
编译器: MinGW64,g ++ 8.1.0(我应该使用MSVC编译代码吗?)