int comparison vs double comparison

April 1st, 2008

เมื่ออาทิตย์ที่แล้ว ได้ไปเถียงกับ postdoc ที่ค่อนข้างมั่นใจในตัวเอง และปากดีพอตัว เค้าเป็น super expert ใน statistic แต่ในเรื่องเขียนโปรแกรมเนี่ยผมว่าไม่ค่อย expert(แต่เก่งพอตัวแหละ) ประเด็นมีอยู่ว่า มี function นึงที่ expensive สุด ๆ และถูก call บ่อยโคตร ๆ เพราะฉะนันสมควรต่อการ optimize มาก postdoc ต้องการให้ผมเขียน array ของจำนวนเต็มโดยใช้ Library ที่มีอยู่แล้วด้วยซึ่งมันดั๊นรับได้แต่ double แต่ว่ามี method เท่ๆ แบบ inverse และ decomposition แทบทุกแบบ (point เค้าก็ดีนะ) ผมก็เถียงกลับไปว่า (จะบ้าหรอ)double comparison เนี่ยช้ากว่า integer comparison สุด ๆ และ fancy matrix operation เนี่ยไม่มีความหมายในปัญหาที่เรากำลังทำ (ถ้ารู้ assembly งู ๆ ปลา ๆ ก็จะรู้ว่า int comparison เนี่ย CMP หนึ่งอัน double comparison เนี่ย ทั้ง CMPSS JUMP MOV RET และอื่น ๆ อีกมากมาย)

แล้ว postdoc คนนั้นก็พยายาม disprove ผมด้วยการเขียน code ดังนี้

	
int main(int argc, char** argv)
{
  int n = 100000;
  int m = 100000;
	
  cout << n << \" \" << m << endl;
	
  /*
  int x1 = 0;
  int x2 = 1;
  */
	
  double x1 = 0;
  double x2 = 0;
	
  for( int i= 0;i< n;i++ )
    for( int j= 0;j< m;j++ )
      //      bool yes = ( x1 == x2 );
      bool yes = ( fabs(x1-x2)<0.5 );
	
  return 0;
}


compile ด้วย gcc/g++ O2 แล้วเค้าก็ time ปรากฏว่า มันเท่ากัน…. การเขียนแบบนี้เป็นการแสดงถึงความไม่เข้าใจว่า compiler มันทำบ้าอะไรกับ code
แน่นอนมันต้องเท่ากันสิ ด้วยเหตุผลว่า O2มัน optimize code แล้วสิ่งแรก ๆ ที่มันทำคือ เอาของที่ไม่ได้เกี่ยวกับ index ของ loop ออกจาก loop
Before

  for( int i=0;i< n;i++ )
    for( int j=0;j< m;j++ )
      //      bool yes = ( x1 == x2 );
      bool yes = ( fabs(x1-x2)< 0.5 );

After

//      bool yes = ( x1 == x2 );
bool yes = ( fabs(x1-x2)< 0.5 );
  for( int i=0;i< n;i++ )
    for( int j=0;j< m;j++ )
      {//do nothing;}

และสิ่งต่อไป(หรือก่อนหน้านี่ก็เป็นไปได้)ที่มันจะทำคือ เอา variable ที่ compute แล้วไม่เคยไปสร้าง side effect กับอะไรเลยออกไป
Even better

//do nothing since it's not gonna be used

cout กับ n m ยังอยู่นะเพราะมันมี side effect เพื่อเป็นการตอบกลับไปผมก็แสดงพลัง hack ด้วยการ abuse compiler ด้วย code ต่อไปนี้

int main(int argc, char** argv)
{
	
  int size = 100000000;
  int* array = new int[size];
  int* endofarray = &(array[size-2]);
  int* pointer = array;
  /*
  double* array = new double[size];
  double* endofarray = &(array[size-2]);
  double* pointer = array;
  */
  bool yes=true;
  for( ;pointer< endofarray;pointer++ ){
    //cout << (*pointer) << endl;
    yes &= (*pointer)==(*(pointer+1));
    //yes &= fabs((*pointer)-(*(pointer+1)))<0.5;
	
  }
  cout << yes << endl;
  return 0;
}

ถ้าเพิ่งเรียน c หรือ c++ อ่านแล้วอาจจะบอกได้ว่าเขียนไร(วะ) ไอ้บ้า แต่สรุปคือ ผมทำให้ program assume input ไม่ได้(ขอ chunk ของ memory แล้วไม่ได้ initialize most of the time คุณจะได้ 0 มา), เอาของออกจาก loop ไม่ได้เพราะ ของใน loop เกี่ยวกับ index ใน loop, และ cout เพื่อทำให้ yes มี side effect แล้วก็ compile ด้วย O2 แล้วก็ run…ปรากฏความต่างอย่างน้อย 2 เท่าระหว่าง int comparison และ double comparison (ยังไม่ได้เอา over head ออกนะเนี่ย)

เรื่องนี้สอนให้รู้ว่า…จำไว้ว่า code ที่เขียนกับ code ที่ compile เนี่ยมันไม่เหมือนกันนะจ้ะ

Entry Filed under: Uncategorized

1 Comment Add your own

  • 1. นกแอร์  |  April 3rd, 2008 at 5:32 am

    เขียนอธิบายแบบว่า อ่านแล้วงงมากๆ *_*

Leave a Comment

Required

Required, hidden

Some HTML allowed:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>

Subscribe to the comments via RSS Feed


Calendar

April 2008
M T W T F S S
« Jan   May »
 123456
78910111213
14151617181920
21222324252627
282930  

Most Recent Posts