为什么我使用InterlockedIncrement来增加关键变量,但仍然得到错误的答案?

时间:2019-06-18 14:46:25

标签: c++ winapi g++

我是否错误地使用了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编译代码吗?)

0 个答案:

没有答案