저는 멀티 스레드 프로그래밍을 처음 접했고 C++ 11에서 std::atomic
을 발견했습니다.어떻게하면 C++ 11 std :: atomic을 제대로 늘릴 수 있습니까?
그래서 원자력 작업에 소요되는 시간을 파악하려고했습니다.
using namespace std;
using namespace std::chrono;
constexpr int NUM_THREADS = 8;
constexpr int LIMIT = 100000;
atomic<int> sum = 0;
void foo(int idx) {
while (true) {
if (sum.load() >= LIMIT) {
return;
}
sum.fetch_add(1);
}
}
main
과 :
int main(void) {
thread threads[NUM_THREADS];
auto start = high_resolution_clock::now();
for (int i = 0; i < NUM_THREADS; i++) {
threads[i] = thread(&foo, i);
}
for (int i = 0; i < NUM_THREADS; i++) {
threads[i].join();
}
auto du = high_resolution_clock::now() - start;
cout << "computing time\t\t" << duration_cast<milliseconds>(du).count() << "ms" << endl;
cout << "number of thread\t" << NUM_THREADS << endl;
cout << "sum\t\t\t" << sum << endl;
return 0;
}
그러나 sum
가 LIMIT
동일 항상하지
제가 아는 바로는 atomic 연산은 '호출'될 때 스레드로부터 안전합니다. 그래, 내 코드가 잘못되었다고 생각하지만이 작업을 올바르게 수행하는 방법을 찾지 못했습니다.
main
으로 어떻게 정확한 결과를 얻을 수 있습니까? 이 코멘트에 말한 것처럼 문제는 변수 것을
(물론,이 버전은 sum
및 LIMIT
동일 할 것입니다,하지만 난이 좋은 방법이 아니라고 생각 ...)
void foo(int idx) {
for (int i = 0; i < LIMIT/NUM_THREADS; i++) {
sum.fetch_add(1);
}
}
첫 번째 검사는 귀하의 수표와 증분이 두 개의 별도 작업이므로 두 개의 스레드가 잠재적으로 LIMIT보다 낮은 값을 읽을 수 있고 둘 다 증가 할 수 있습니다. – Borgleader
문제는 원자를 증가시키는 방법이 아닙니다. 문제는 원자 적으로 * 두 개의 연산을 수행하는 방법입니다. – Hurkyl
http://en.cppreference.com/w/cpp/atomic/atomic/compare_exchange 또는 뮤텍스가 필요합니다. –