protect
ถ้าเอาบทความไปเผยแพร่แล้วไม่ให้เครดิต ดำเนินคดีด้วย พรบ. คอมพิวเตอร์ฉบับใหม่ ขั้นสูงสุดและไม่ยอมความครับ
วันอังคารที่ 18 สิงหาคม พ.ศ. 2558
ทดสอบ ประสิทธิภาพของ JITCompiler ตอนที่ 2
มาต่อจากบทความที่แล้วกันเลยน่ะครับ
3. QueryPerformanceCounter ของ Kernel32.dll
ระบบปฏิบัติการ Windows มี UnManaged library สำหรับให้นักพัฒนาได้นำไปใช้กัน function QueryPerformanceCounter ก็เป็นหนึ่งในนั้นโดย function นี้จะอยู่ใน file Kernel32.dll
วิธีการใช้ QueryPerformanceCounter ตามตัวอย่าง code ข้างล่างเลยครับ
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
namespace HelloWorld
{
class Program
{
[DllImport("Kernel32.dll")]
public static extern void QueryPerformanceCounter(ref long freq);
[DllImport("Kernel32.dll")]
public static extern void QueryPerformanceFrequency(ref long ticks);
static void Main(string[] args)
{
for (int NumberOfTry = 0; NumberOfTry < 3; NumberOfTry++)
{
TestCounter();
Console.WriteLine("Press any key to do one more time");
Console.ReadLine();
}
}
static void TestCounter()
{
long frequency = 0;
long start = 0, stop = 0;
Decimal microsec = new Decimal(1.0e6);
Decimal nanosec = new Decimal(1.0e9);
QueryPerformanceFrequency(ref frequency);
QueryPerformanceCounter(ref start);
long total = 0;
for (int i = 0; i < 1000000; i++)
total += i;
QueryPerformanceCounter(ref stop);
double duration = (( (double)(stop - start) / (double)frequency) ) ;
Console.WriteLine("Duration (microsecond) = " + ((duration * (double)microsec)).ToString());
Console.WriteLine("Duration (nanosecond) = " + (duration * (double)nanosec).ToString());
}
}
}
เรามาลองดู code ที่ล่ะส่วนกันน่ะครับ
[DllImport("Kernel32.dll")]
public static extern void QueryPerformanceCounter(ref long freq);
[DllImport("Kernel32.dll")]
public static extern void QueryPerformanceFrequency(ref long ticks);
จาก code ข้างบนจะเป็นการบอก JITCompiler ว่าเราจะมีการเรียกใช้ function ที่ชื่อ QueryPerformanceCounter และ QueryPerformanceFrequency จาก library file ที่ชื่อว่า Kernel32.dll เนื่องจาก library Kernel32.dll เป็นชนิด UnManaged Code จึงต้องกำหนด Attribute ของ function ให้ไปเรียกใช้ตัว code ที่ Kernel32.dll หมายความว่าเมื่อ C# เรียกใช้ function QueryPerformanceCounter หรือ QueryPerformanceFrequency JITCompiler จะไปเรียกใช้ function QueryPerformanceCounter หรือ QueryPerformanceFrequency จาก Kernel32.dll
Decimal microsec = new Decimal(1.0e6);
Decimal nanosec = new Decimal(1.0e9);
code ข้างบนสามารถเขียนแทนได้ด้วย
Decimal microsec = 1000000;
Decimal nanosec = 1000000000;
สำหรับผมเลข 0 มันเยอะไปเลยเขียนให้ย่อๆ เพื่อนอ่าน code ง่ายและลดความผิดพลาดในการพิมพ์ครับ
สำหรับคำสั่ง QueryPerformanceFrequency(ref frequency); จะเป็นการถาม frequency ของ performance-counter ของระบบปฏิบัติการ ค่านี้จะถูก setup ทุกครั้งที่มีการเปิดเครื่องคอมพิวเตอร์ หน่วยที่ได้จะเป็นจำนวบนับต่อวินาที (counts per second)
คำสั่ง QueryPerformanceCounter(ref start); เป็นการบอกให้เริ่มต้นจับเวลาและคำสั่ง
QueryPerformanceCounter(ref stop); เป็นการสั่งให้หยุดจับเวลา
ถ้าเราเอา start กับ stop มาลบกันจะเป็นจำนวน counts ที่ CPU ได้ทำงานในช่วงที่ counter start จนกระทั่ง counter stop โดยที่มีหน่วยเป็น counts
ดังนั้นเมื่อนำเอาจำนวน start - stop แล้วเอามาหาร frequency (ที่มีหน่วยเป็น counts per second) ค่าที่ได้จึงเป็นระยะเวลาระหว่าง start ถึง stop ในหน่วยของวินาที
ผลลัพท์ที่ได้จากการรัน code
จะเห็นว่าเมื่อเรา execute function ครั้งแรกจะกินเวลามากกว่าเป็นเพราะ CPU ต้องเสียเวลา compile IL code ตอน runtime แต่หลังจากตรั้งที่ 2 เป็นต้นไปเวลาในการทำงานก็จะน้อยลง สิ่งที่สังเกตุได้คือเวลาที่ compile IL code น้อยมากๆ ในความเห็นของผมเป็นตัวเลขที่ผมยอมรับได้ครับ
พบกันใหม่บทความหน้าครับ
TuChay
สมัครสมาชิก:
ส่งความคิดเห็น (Atom)
ไม่มีความคิดเห็น:
แสดงความคิดเห็น