thread::hardware_concurrency() 를 통한 최적 코어 수 활용std::thread와 std::async/future 방식 모두 실험IsPrime()bool IsPrime(int number)
{
if (number <= 1)
return false;
if (number == 2 || number == 3)
return true;
for (int i = 2; i < number; i++)
{
if (number % i == 0)
return false;
}
return true;
}
2와 3은 예외적으로 소수로 처리2부터 number-1까지 나눠 떨어지는 수가 있으면 소수가 아님📌 Tip: 실제 성능 향상을 위해선 i <= sqrt(number)까지만 순회해도 되지만, 여기선 단순 구현!
CountPrime()int CountPrime(int start, int end)
{
int count = 0;
for (int number = start; number <= end; number++)
{
if (IsPrime(number))
count++;
}
return count;
}
std::threadint main()
{
const int MAX_NUMBER = 1'000'000;
vector<thread> threads;
int coreCount = thread::hardware_concurrency();
int jobCount = (MAX_NUMBER / coreCount) + 1;
atomic<int> primeCount = 0;
for (int i = 0; i < coreCount; i++)
{
int start = (i * jobCount) + 1;
int end = min(MAX_NUMBER, ((i + 1) * jobCount));
threads.push_back(thread([start, end, &primeCount]()
{
primeCount += CountPrime(start, end);
}));
}
for (thread& t : threads)
t.join();
cout << primeCount << endl;
}
hardware_concurrency())atomic<int>으로 공유 자원(primeCount)의 데이터 레이스 방지thread.join()으로 모든 쓰레드 종료 대기std::async + shared_futureint main()
{
const int MAX_NUMBER = 1'000'000;
const int MAX_THREAD = thread::hardware_concurrency();
int stepVal = MAX_NUMBER / MAX_THREAD;
int sum = 0;
vector<shared_future<int>> futures;
for (int i = 1; i <= MAX_THREAD; ++i)
{
shared_future<int> f = async(launch::async, CountPrime, stepVal * (i - 1), stepVal * i);
futures.push_back(f);
}
if (stepVal * MAX_THREAD < MAX_NUMBER)
{
sum += CountPrime(stepVal * MAX_THREAD + 1, MAX_NUMBER);
}
for (auto& f : futures)
sum += f.get();
cout << sum << endl;
}
async를 이용해 비동기 호출로 작업 수행shared_future를 통해 복수 참조 가능get() 호출로 각 작업 결과 수집| 방식 | 1,000,000 소수 계산 시간 | 특징 |
|---|---|---|
std::thread | 더 빠름 | 직접 제어, 가벼움 |
std::async | 조금 느림 | 코드 간결함, 내부 제어 비용 있음 |