I started learning programming with multi-threads and i have program. My program is slower with multi-threads: multi-threads: ~ 8.5 sec without multi-threads: ~ 4.96 Someone can explain me what is wrong with my code?
#include <iostream>
#include <thread>
#include <ctime>
using namespace std;
long long even_sum = 0;
long long odd_sum = 0;
void findEvenNumber(int start, int end){
for(int i=start;i<end;i ){
if(i%2==0){
even_sum ;
}
}
}
void findOddNumber(int start, int end){
for(int i=start;i<end;i ){
if(i%2==1){
odd_sum ;
}
}
}
void multiTask(){
thread t1(findEvenNumber,1,1000000000);
thread t2(findOddNumber,1,1000000000);
t1.join();
t2.join();
}
void noMultiTask(){
findEvenNumber(1,1000000000);
findOddNumber(1,1000000000);
}
int main(){
clock_t start = clock();
//noMultiTask();
//multiTask();
clock_t end = clock();
cout<<(double)(end - start)/CLOCKS_PER_SEC<<endl;
cout<<even_sum<<" "<<odd_sum<<endl;
return 0;
}
CodePudding user response:
At minimum, you have a false sharing problem. even_count
and odd_count
are almost certainly on the same cache line, which means when you want to touch one variable you're actually forcing the other thread to have its cacheline invalidated. There's more to false sharing than this, but for a quick overview there's a great talk by Scott Meyers that hits on it at the start: https://www.youtube.com/watch?v=WDIkqP4JbkE
By using local variables for odd/even count and only updating the globals at the end of the thread, I get much better performance on my system (1.23299 seconds vs 1.07338).
void findEvenNumber(int start, int end){
auto count = 0;
for(int i=start;i<end;i ){
if(i%2==0){
count ;
}
}
even_sum = count;
}
void findOddNumber(int start, int end){
auto count = 0;
for(int i=start;i<end;i ){
if(i%2==1){
count ;
}
}
odd_sum = count;
CodePudding user response:
The multi-threaded version has to launch threads and wait for them to complete. The non-multi-threaded version doesn't. So it makes sense that the multi-threaded version would take more CPU time.
The multi-threaded version does take less wall time.