• C++11特性原子类型——多原子类型并行访问的串行化测试


    /*C++11 原子类型测试
      问题:如果有多个原子需要操作,如何保障并行的序列化
    */  
    
    #include <thread>
    #include <stdlib.h>
    #include <atomic> 
    #include <iostream>
    #include <time.h>
    #include <vector>
    #include "mytimer.h"
    
    using namespace std;
    
    //用原子数据类型作为共享资源的数据类型
    atomic_long total(0);
    atomic_int i(0);
    //long total = 0;
    
    TimeVal a, b;
    
    void click()
    {
    	//由于有两个原子类型,必须保证更新的顺序性
        while (i++ < 10000000)  //原子操作,保障了顺序操作
            total += 1;        //
    	/*错误
    		while(i < 1000000)   //一次读取
    		{
    			i++;    //上次读取i到这里未防止再次读取i的值
    			total++;
    		}
    	*/
    }
    
    //如果用单线程计算的话
    long commonclick()
    {	
    	long total = 0;
    	for(int i = 0; i < 	10000000; i++)
    		total++;
    	return total;
    }
    
    int main(int argc, char* argv[])
    {
    	int N = 16;
    	double time0, time1;
    	if (argc == 2)
    		N = atoi(argv[1]);
    	
    	//主线程测试
    	get_current_time( a );
    	long val = commonclick();
    	get_current_time( b );
    	cout << "Main thread" << endl;
    	cout<<"result:"<<val<<endl;
    	time0 = getDeltaTime(b, a) * 1e3;
        cout<<"duration:"<< time0 <<"ms"<<endl;	
    	
    	cout << "Single thread" << endl;
    	//单线程测试
    	get_current_time( a );
    	thread t1(commonclick);
    	t1.join();
    	get_current_time( b );
        cout<<"duration:"<< getDeltaTime(b, a) * 1e3 <<"ms"<<endl;	
    	
    	cout << "Multi thread " << N << endl;
        // 计时开始
        get_current_time( a );
        // 创建N个线程模拟点击统计
        vector<thread> threads(N);
        for(int i=0; i<N;++i) 
        {
            threads[i] = thread(click);
        }
        for(int i=0; i<N;++i) 
    		threads[i].join();
        // 计时结束
        get_current_time( b );
        // 输出结果
        cout<<"result:"<<total<<endl;
    	time1 = getDeltaTime(b, a) * 1e3;
        cout<<"duration:"<< time1 <<"ms"<<endl;
    	
    	cout << "Delay for each thread: " << time1 / N - time0 << "ms, about " << time1/N / time0 << " time of main thread." << endl;
    
        return 0;
    }


    mytimer.h文件

    #ifndef __MYGLIB_H__
    #define __MYGLIB_H__
    
    #include <windows.h>
    
    typedef LARGE_INTEGER TimeVal;
    LARGE_INTEGER freq;
    
    void get_current_time(TimeVal& s)
    {
    	QueryPerformanceFrequency(&freq);
    	QueryPerformanceCounter(&s);    
    }
    
    double getDeltaTime(TimeVal t2, TimeVal t1)
    {
    	double time = (double)(t2.QuadPart-t1.QuadPart)/(double)freq.QuadPart;  
    	return time;
    }
    
    #endif


    编译:

    g++ -std=c++11 atomic_par.cpp

    运行结果:

    运行a 2

    Main thread
    result:10000000
    duration:25.7743ms
    Single thread
    duration:29.4485ms
    Multi thread 2
    result:10000000
    duration:372.861ms
    Delay for each thread: 160.656ms, about 7.23319 time of main thread.

    运行a 4

    Main thread
    result:10000000
    duration:22.2332ms
    Single thread
    duration:23.3911ms
    Multi thread 4
    result:10000000
    duration:472.065ms
    Delay for each thread: 95.783ms, about 5.3081 time of main thread.

    运行a 8

    Main thread
    result:10000000
    duration:22.2252ms
    Single thread
    duration:22.7899ms
    Multi thread 8
    result:10000000
    duration:468.485ms
    Delay for each thread: 36.3355ms, about 2.63488 time of main thread.

    运行a 16

    Main thread
    result:10000000
    duration:22.399ms
    Single thread
    duration:23.7603ms
    Multi thread 16
    result:10000000
    duration:489.68ms
    Delay for each thread: 8.20599ms, about 1.36636 time of main thread.

    从最后结果看,每个线程由于任务少了,所用时间短了,但总的系统用于线程调度的时间多了。

  • 相关阅读:
    poj 2533 (LIS 最长递增子序列)
    zoj 2432(最长递增上升子序列)
    hdu 1159(最长公共子序列)
    2013 腾讯马拉松初赛 第1场
    poj 1458(最长公共子序列)
    hdu 4524(水题)
    hdu 4514(自己添加栈—— #pragma comment(linker, "/STACK:102400000,102400000" ))
    MVC3安装报错解决方案
    C# 用7Z 压缩 ZIP
    获得字符串中开始和结束字符串中间得值
  • 原文地址:https://www.cnblogs.com/javawebsoa/p/3020115.html
Copyright © 2020-2023  润新知