Tagged: 编程 Toggle Comment Threads | 键盘快捷键

  • jinzihao pm6:33 on 2016年8月29日 链接地址 | 回复
    Tags: , 编程   

    C语言判断奇偶性:i&1和i%2 

    三个月前的一篇文章中,曾经好奇为什么C语言中同样是判断整数奇偶性,在不开编译优化(gcc -O0)的情况下,

    (1) bool isOdd = i & 1;

    (2) bool isOdd = i % 2;

    略快(但并没有快很多)。

    看过反汇编得到的汇编代码,发现即便没有开编译优化选项,编译器对于(2)也没有使用除法指令idiv,从而避免了(2)比(1)慢得多的情况。编译器由(2)编译出的汇编代码的作用,是保存一个临时变量t,如果需要判断奇偶性的数i是正数,则t取0,否则t取1;“i是否为奇数”则可以表示为((i + t) & 1) – t,这样就会比i & 1稍慢(但不会慢很多)。

    实际上(1)对于i为负数的情况会得到错误的结果,因此(2)的一点点额外的时间开销是完全有必要的;如果将上一篇文章main函数里面的int全部改为unsigned int,即使在指定gcc -O0的情况下,编译器也会对(1)和(2)编译出完全相同的汇编代码,即(2)也会被优化为i & 1。

     

     
    • 陈文 下午3:25 on 2016年9月9日 链接地址 | 回复

      你的网站用teleport下载文件只有60k/s,很多文件下载半天也下载不下来

    • 陈文 下午3:26 on 2016年9月9日 链接地址 | 回复

      另外问一下,这个网页http://netmite.com/android/srv/2.0/getapk.php的小玩意怎么放在我的网站上运行

  • jinzihao pm6:58 on 2016年6月28日 链接地址 | 回复
    Tags: 二次误差法, , 编程, 网格简化   

    图形学大作业之网格简化 

    已开源:https://github.com/jinzihao/MeshSimplification

    本程序依照Surface Simplification Using Quadric Error Metrics(https://www.cs.cmu.edu/~./garland/Papers/quadrics.pdf)实现

    效果如图:
    dinosaur1

    dinosaur2

    dinosaur3

    dinosaur4

    dinosaur5

    dinosaur6

    dinosaur7

     
  • jinzihao pm6:41 on 2016年6月28日 链接地址 | 回复
    Tags: Hall模型, Phong模型, Whitted模型, 光线跟踪, 凹凸贴图, , 编程   

    图形学大作业之光线跟踪 

    已开源:https://github.com/jinzihao/RayTracing
    效果如图:
    17

     
  • jinzihao pm9:37 on 2016年4月18日 链接地址 | 回复
    Tags: , 编程   

    连续地访问内存TLB是否命中在运行时间上会有很大差别,例如:

    #include <stdio.h>
    
    int main() {
      int *a = new int[4096 * 4096];
      for (int i = 0; i < 4096; ++i) {
        for (int j = 0; j < 4096; ++j) {
          // a[(j << 12) + (i << 0)] = 0; // 0.4004s
          // a[(j << 11) + (i << 1)] = 0; // 0.3810s
          // a[(j << 10) + (i << 2)] = 0; // 0.3809s
          // a[(j << 9) + (i << 3)] = 0; // 0.3548s
          // a[(j << 8) + (i << 4)] = 0; // 0.3503s
          // a[(j << 7) + (i << 5)] = 0; // 0.2727s
          // a[(j << 6) + (i << 6)] = 0; // 0.2691s
          // a[(j << 5) + (i << 7)] = 0; // 0.1434s
          // a[(j << 4) + (i << 8)] = 0; // 0.1195s
          // a[(j << 3) + (i << 9)] = 0; // 0.0714s
          // a[(j << 2) + (i << 10)] = 0; // 0.0651s
          // a[(j << 1) + (i << 11)] = 0; // 0.0681s
           a[(j << 0) + (i << 12)] = 0; // 0.0825s
        }
      } 
      return 0;
    }
    

    上述程序中循环体内有13个版本的代码,每次编译只启用其中1行,注释掉其余的12行,测量运行时间。

    每次访问内存地址的增量从16KB逐次折半,到最后每次增量为4byte,内存访问操作由第一个版本100%的TLB miss,到第4个版本TLB miss开始降至50%(假设页大小为4KB),此后TLB miss比例逐次减半,直到最后几乎100%的TLB hit(1023/1024),此过程中运行时间不断下降。

    问题:最后一个版本的运行时间明显上升,且多次实验结果均无改变,不知该如何解释?

     

     
  • jinzihao pm7:19 on 2015年6月15日 链接地址 | 回复
    Tags: , 编程   

    C++的(a, b, c, …, n)有个奇特的用法:输出括号中最后一个数,不知道为什么这样设计…

    #include 
    using namespace std;
    
    int func0() {
    	cout << "[func0]";	
    	return 0;
    }
    
    int func1() {
    	cout << "[func1]";	
    	return 1;
    }
    
    int func2() {
    	cout << "[func2]";	
    	return 2;
    }
    
    int main() {
    	cout << (func2(), func1(), func0()) << endl;
    	cout << (func0() && func1() && func2()) << endl;
    	return 0;
    }
    
     
    • Jincheng Zhang 上午10:15 on 2015年6月16日 链接地址 | 回复

      话说我之前一直不知道这个…高中信息课时候被老师考住了…like while(a=cin.getline(),cin.good())后来acm见识到了(语法大概这样,可能有误)

  • jinzihao pm12:12 on 2015年6月4日 链接地址 | 回复
    Tags: 编程   

    有些代码中会出现一个“魔数”1e9 + 7 (1000000007),是一个防止溢出的取模运算常用的大质数;另外13331也常在hash函数中用来取模

     
  • jinzihao pm9:55 on 2015年5月27日 链接地址 | 回复
    Tags: , 编程   

    C++的ifstream读入文件时如果要原样保留空格和换行,可以用ios::binary模式读取:

        	ifstream fin(FILENAME, ios::in | ios::binary);
        	while (fin.read(BUFFER, 256)) {
        		TEXT.append(BUFFER);
       		}
    
     
  • jinzihao pm5:08 on 2015年5月10日 链接地址 | 回复
    Tags: , 编程   

    C++的reinterpret_cast类似union,不对变量的二进制内容做任何处理,直接当作另一类型来操作,但只能对指针做强制类型转换;C语言风格的强制类型转换如果作用在非指针的变量上,会对变量的二进制内容进行一定的处理(例如整数的8可以转换为浮点数的8.0),如果作用在指针上则和reinterpret_cast无异:
    Input:

    	int a = 8;
    	int *aptr = &a;
    	int b = (float)a;
    	float *bptr = reinterpret_cast(aptr);
    	int *cptr = &a;
    	float *dptr = (float*)cptr;
    	cout << a << " " << *aptr << " " << b << " " << *bptr << " " << *cptr << " " << *dptr << endl;
    

    Output:

    8 8 8 1.12104e-044 8 1.12104e-044
    
     
  • jinzihao pm7:36 on 2015年5月5日 链接地址 | 回复
    Tags: , 编程   

    C++的多重继承:
    http://www.learncpp.com/cpp-tutorial/117-multiple-inheritance/

     
  • jinzihao pm7:00 on 2015年5月2日 链接地址 | 回复
    Tags: , 编程   

    辨析list, vector和deque:
    http://cutely606.blog.163.com/blog/static/26607977201191653517926/

     
  • jinzihao pm3:49 on 2015年4月28日 链接地址 | 回复
    Tags: , 编程   

    Input:

    float x[5] = {1, 2, 3, 4, 5};
    cout << (&x[0])[4] << endl;
    

    Output:

    5
    
     
  • jinzihao pm3:41 on 2015年4月28日 链接地址 | 回复
    Tags: , 编程   

    #include 
    #include  
    using namespace std;  
    
    class test {
    public:
    	test(){}
    	~test(){}
    	
    	test& operator ()(const std::string& _name,const std::string _dest = "") {
    		name = _name;
    		dest = _dest;
    		return *this;
    	}
    	inline std::string getName(){return name;}
    	inline std::string getDest(){return dest;}
    private:
    	std::string name;
    	std::string dest;
    };
    
    
    int main() {//.addoption()
    	test Ctest;
    	Ctest("1","a")("2","b")("3","c");//.operator ()	
    	std::cout << "name:" << Ctest.getName() << " dest:" << Ctest.getDest() << std::endl;
    }
    
     
  • jinzihao am9:50 on 2015年4月13日 链接地址 | 回复
    Tags: , 编程   

    #include 
    using namespace std;
    
    int &test1();
    int &test2();
    int &test3();
    
    int main() {
    	int &y1 = test1();
    	int &y2 = test2();
    	int &y3 = test3();
    	cout << y1 << " " << y2 << " " << y3 << endl;
    	for (int i = 0; i < 8; i++) {
    		y1++;
    	}
    	for (int i = 0; i < 16; i++) {
    		y2++;
    	}
    	for (int i = 0; i < 32; i++) {
    		y3++;
    	}
    	cout << y1 << " " << y2 << " " << y3 << endl;
    	return 0;
    }
    
    int &test1() {
    	int x = 42;
    	return x;
    }
    
    int &test2() {
    	int x = 42;
    	return x;
    }
    
    int &test3() {
    	static int x = 42;
    	return x;
    }
    

    运行结果:

    42 42 42
    24 24 74
    
     
  • jinzihao pm11:12 on 2015年4月7日 链接地址 | 回复
    Tags: 并行计算, 编程   

    针对向量化进行优化的实验:
    在使用g++ -O3编译的条件下,向量化将运行时间降至baseline的38.4%
    在使用icc -O3编译的条件下,向量化将运行时间降至baseline的25.3%

    baseline:

    #include 
    #include 
    #include 
    #include 
    using namespace std;
    
    double matrix[102][102][102];
    int main(int argc, char **argv) {
    	
    	if (argc != 3) {
    		cout << "Usage: ./1  " << endl; 
    		return 0;
    	}
    	
    	const int dimX = 100; 
    	const int dimY = 100; 
    	const int dimZ = 100; 
    	
    	cout << "Loading data... ";
    	ifstream fin(argv[1]);
    	for (int i = 1; i < dimX + 1; i++) {
    		for (int j = 1; j < dimY + 1; j++) {
    			for (int k = 1; k < dimZ + 1; k++) {
    				char buffer[100];
    				fin >> buffer;
    				matrix[i][j][k] = atof(buffer);
    			}
    		}
    	}
    	cout << "complete." << endl;
    	
    	int times = atoi(argv[2]);
    	
    	timeval t1;
    	gettimeofday (&t1, NULL); 
    	for (int n = 0; n < times; n++) {
    		for (int i = 1; i < dimX + 1; i++) {
    			for (int j = 1; j < dimY + 1; j++) {
    				for (int k = 1; k < dimZ + 1; k++) {
    					matrix[i][j][k] = (matrix[i][j][k-1] + matrix[i][j][k+1] + matrix[i][j-1][k] + matrix[i][j+1][k] + matrix[i-1][j][k] + matrix[i+1][j][k]) / 6;
    				}
    			}
    		}
    	}
    	timeval t2;
    	gettimeofday (&t2, NULL); 
    	
    	cout << "Time elapsed: " << (t2.tv_sec - t1.tv_sec) * 1000000 + t2.tv_usec - t1.tv_usec << " microseconds" << endl;
    	return 0;
    }
    

    针对向量化优化的版本:

    #include 
    #include 
    #include 
    #include 
    using namespace std;
    
    double matrix[102][102][102];
    int main(int argc, char **argv) {
    	
    	if (argc != 3) {
    		cout << "Usage: ./1  " << endl; 
    		return 0;
    	}
    	
    	const int dimX = 100; 
    	const int dimY = 100; 
    	const int dimZ = 100; 
    	
    	cout << "Loading data... ";
    	ifstream fin(argv[1]);
    	for (int i = 1; i < dimX + 1; i++) {
    		for (int j = 1; j < dimY + 1; j++) {
    			for (int k = 1; k < dimZ + 1; k++) {
    				char buffer[100];
    				fin >> buffer;
    				matrix[i][j][k] = atof(buffer);
    			}
    		}
    	}
    	cout << "complete." << endl;
    	
    	int times = atoi(argv[2]);
    	
    	timeval t1;
    	gettimeofday (&t1, NULL); 
    	for (int n = 0; n < times; n++) {
    		for (int i = 1; i < dimX + 1; i+=2) {
    			for (int j = 1; j < dimY + 1; j+=2) {
    				for (int k = 1; k < dimZ + 1; k+=2) {
    					matrix[i][j][k] = (matrix[i][j][k-1] + matrix[i][j][k+1] + matrix[i][j-1][k] + matrix[i][j+1][k] + matrix[i-1][j][k] + matrix[i+1][j][k]) / 6;
    				}
    				for (int k = 2; k < dimZ + 1; k+=2) {
    					matrix[i][j][k] = (matrix[i][j][k-1] + matrix[i][j][k+1] + matrix[i][j-1][k] + matrix[i][j+1][k] + matrix[i-1][j][k] + matrix[i+1][j][k]) / 6;
    				}
    			}
    			for (int j = 2; j < dimY + 1; j+=2) {
    				for (int k = 1; k < dimZ + 1; k+=2) {
    					matrix[i][j][k] = (matrix[i][j][k-1] + matrix[i][j][k+1] + matrix[i][j-1][k] + matrix[i][j+1][k] + matrix[i-1][j][k] + matrix[i+1][j][k]) / 6;
    				}
    				for (int k = 2; k < dimZ + 1; k+=2) {
    					matrix[i][j][k] = (matrix[i][j][k-1] + matrix[i][j][k+1] + matrix[i][j-1][k] + matrix[i][j+1][k] + matrix[i-1][j][k] + matrix[i+1][j][k]) / 6;
    				}
    			}
    		}
    		for (int i = 2; i < dimX + 1; i+=2) {
    			for (int j = 1; j < dimY + 1; j+=2) {
    				for (int k = 1; k < dimZ + 1; k+=2) {
    					matrix[i][j][k] = (matrix[i][j][k-1] + matrix[i][j][k+1] + matrix[i][j-1][k] + matrix[i][j+1][k] + matrix[i-1][j][k] + matrix[i+1][j][k]) / 6;
    				}
    				for (int k = 2; k < dimZ + 1; k+=2) {
    					matrix[i][j][k] = (matrix[i][j][k-1] + matrix[i][j][k+1] + matrix[i][j-1][k] + matrix[i][j+1][k] + matrix[i-1][j][k] + matrix[i+1][j][k]) / 6;
    				}
    			}
    			for (int j = 2; j < dimY + 1; j+=2) {
    				for (int k = 1; k < dimZ + 1; k+=2) {
    					matrix[i][j][k] = (matrix[i][j][k-1] + matrix[i][j][k+1] + matrix[i][j-1][k] + matrix[i][j+1][k] + matrix[i-1][j][k] + matrix[i+1][j][k]) / 6;
    				}
    				for (int k = 2; k < dimZ + 1; k+=2) {
    					matrix[i][j][k] = (matrix[i][j][k-1] + matrix[i][j][k+1] + matrix[i][j-1][k] + matrix[i][j+1][k] + matrix[i-1][j][k] + matrix[i+1][j][k]) / 6;
    				}
    			}
    		}
    	}
    	timeval t2;
    	gettimeofday (&t2, NULL); 
    	
    	cout << "Time elapsed: " << (t2.tv_sec - t1.tv_sec) * 1000000 + t2.tv_usec - t1.tv_usec << " microseconds" << endl;
    	return 0;
    }
    
     
  • jinzihao pm10:12 on 2015年3月30日 链接地址 | 回复
    Tags: , 编程   

    static int, static const int, const int, int 的使用示例:

     #include 
    using namespace std;
    
    class People {
    public:
    	static int w;
    	static const int x1;
    	static const int x2 = 20;
    	const int y1;
    	const int y2 = 30;
    	int z;
    	People (int yy, int zz) : y1(yy), z(zz) {}
    };
    
    int People::w = 10;
    const int People::x1 = 20; 
    int z = 10;
    
    int main()
    {
    	People p(30, 40);
    	cout << p.w << " " << p.x1 << " " << p.x2 << " " << p.y1 << " " << p.y2 << " " << p.z << endl ; 
    }
    

    输出:

    10 20 20 30 30 40
     
c
写新的
j
下一篇文章/下一个回复
k
前一篇文章/以前的回复
r
回复
e
编辑
o
显示/隐藏 回复
t
回到顶部
l
go to login
h
show/hide help
shift + esc
取消