থ্রেড শিডিয়ুলিংয়ের সম্পূর্ণ অনর্থক সমাধান, যা প্রতিটি পরীক্ষার জন্য ঠিক একই সময় পাওয়া উচিত, এটি হ'ল আপনার প্রোগ্রামটি ওএস স্বতন্ত্র হতে সংকলন করা এবং আপনার কম্পিউটার বুট আপ করা যাতে কোনও ওএস-মুক্ত পরিবেশে প্রোগ্রামটি চালানো যায়। তবুও, এটি বেশিরভাগ ক্ষেত্রে অযৌক্তিক এবং সর্বোত্তমভাবে কঠিন হবে।
ওএস-মুক্ত যাওয়ার একটি ভাল বিকল্প হ'ল বর্তমান থ্রেডের সান্নিধ্যকে 1 টি করে সেট করা এবং সর্বোচ্চটিকে অগ্রাধিকার দেওয়া। এই বিকল্পের ধারাবাহিক পর্যাপ্ত ফলাফল সরবরাহ করা উচিত।
এছাড়াও আপনি অপ্টিমাইজেশন যা ডিবাগ, যা গ্রাম ++ অথবা জিসিসি উপায়ে জন্য হস্তক্ষেপ করবে বন্ধ করা উচিত যোগ -Og
কমান্ড লাইন থেকে কোড প্রতিরোধ আউট অপ্টিমাইজ হওয়া থেকে পরীক্ষা করা হচ্ছে। -O0
পতাকা, কারণ এটি অতিরিক্ত অপ্রয়োজনীয় ওভারহেড যা সময়জ্ঞান ফলাফলে অন্তর্ভুক্ত করা হবে প্রবর্তন, এইভাবে কোডের সুবিধানুযায়ী গতি বিকৃতি বোসের ব্যবহার করা উচিত নয়।
বিপরীতে, উভয়ই ধরে নিচ্ছেন যে আপনি "মৃত" কোড নির্মূলকরণের বিষয়টি চূড়ান্ত উত্পাদন তৈরিতে এবং উপেক্ষা করে ব্যবহার করেন -Ofast
(বা খুব কমপক্ষে, -O3
), -Og
খুব কম অপ্টিমাইজেশন সম্পাদন করে -Ofast
; এইভাবে -Og
চূড়ান্ত পণ্যটিতে কোডের আসল গতির ভুল উপস্থাপন করতে পারে।
তদ্ব্যতীত, সমস্ত গতি পরীক্ষা (কিছুটা হলেও) মিথ্যাচার: চূড়ান্ত উত্পাদনের পণ্য সংকলিত -Ofast
প্রতিটি স্নিপেট / বিভাগ / কোডের কার্য বিচ্ছিন্ন নয়; পরিবর্তে, কোডের প্রতিটি স্নিপেট অবিচ্ছিন্নভাবে পরবর্তীটিতে প্রবাহিত হয়, এইভাবে সংকলকটি সমস্ত স্থান থেকে কোডের টুকরোগুলিকে একসাথে যুক্ত হতে, মার্জ করতে এবং অনুকূলিত করতে দেয়।
একই সময়ে, আপনি যদি কোডের স্নিপেটের ভারী ব্যবহার করেন যা এর ভারী ব্যবহার করে realloc()
, তবে কোডের স্নিপেট উচ্চমানের মেমরি বিভাজন সহ একটি উত্পাদন পণ্যগুলিতে ধীর গতিতে চলতে পারে। সুতরাং, "সম্পূর্ণরূপে তার অংশগুলির যোগফলের চেয়েও বেশি" এই অভিব্যক্তিটি এই অবস্থার জন্য প্রযোজ্য কারণ চূড়ান্ত উত্পাদন বিল্ডে কোডটি আপনি যে স্বতন্ত্র স্নিপেটের গতি পরীক্ষা করছেন তার চেয়ে লক্ষণীয়ভাবে দ্রুত বা ধীর হতে পারে।
অসম্পূর্ণতা হ্রাস করতে পারে একটি আংশিক সমাধান মৃত কোড / লুপ নির্মূল প্রতিরোধের জন্য পরীক্ষায় জড়িত ভেরিয়েবল যোগ করার -Ofast
সাথে গতি asm volatile("" :: "r"(var))
পরীক্ষার জন্য ব্যবহার করছে।
উইন্ডোজ কম্পিউটারে স্কোয়ার রুট ফাংশনগুলি কীভাবে বেনমার্ক করবেন তার একটি উদাহরণ এখানে।
// set USE_ASM_TO_PREVENT_ELIMINATION to 0 to prevent `asm volatile("" :: "r"(var))`
// set USE_ASM_TO_PREVENT_ELIMINATION to 1 to enforce `asm volatile("" :: "r"(var))`
#define USE_ASM_TO_PREVENT_ELIMINATION 1
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <chrono>
#include <cmath>
#include <windows.h>
#include <intrin.h>
#pragma intrinsic(__rdtsc)
#include <cstdint>
class Timer {
public:
Timer() : beg_(clock_::now()) {}
void reset() { beg_ = clock_::now(); }
double elapsed() const {
return std::chrono::duration_cast<second_>
(clock_::now() - beg_).count(); }
private:
typedef std::chrono::high_resolution_clock clock_;
typedef std::chrono::duration<double, std::ratio<1> > second_;
std::chrono::time_point<clock_> beg_;
};
unsigned int guess_sqrt32(register unsigned int n) {
register unsigned int g = 0x8000;
if(g*g > n) {
g ^= 0x8000;
}
g |= 0x4000;
if(g*g > n) {
g ^= 0x4000;
}
g |= 0x2000;
if(g*g > n) {
g ^= 0x2000;
}
g |= 0x1000;
if(g*g > n) {
g ^= 0x1000;
}
g |= 0x0800;
if(g*g > n) {
g ^= 0x0800;
}
g |= 0x0400;
if(g*g > n) {
g ^= 0x0400;
}
g |= 0x0200;
if(g*g > n) {
g ^= 0x0200;
}
g |= 0x0100;
if(g*g > n) {
g ^= 0x0100;
}
g |= 0x0080;
if(g*g > n) {
g ^= 0x0080;
}
g |= 0x0040;
if(g*g > n) {
g ^= 0x0040;
}
g |= 0x0020;
if(g*g > n) {
g ^= 0x0020;
}
g |= 0x0010;
if(g*g > n) {
g ^= 0x0010;
}
g |= 0x0008;
if(g*g > n) {
g ^= 0x0008;
}
g |= 0x0004;
if(g*g > n) {
g ^= 0x0004;
}
g |= 0x0002;
if(g*g > n) {
g ^= 0x0002;
}
g |= 0x0001;
if(g*g > n) {
g ^= 0x0001;
}
return g;
}
unsigned int empty_function( unsigned int _input ) {
return _input;
}
unsigned long long empty_ticks=0;
double empty_seconds=0;
Timer my_time;
template<unsigned int benchmark_repetitions>
void benchmark( char* function_name, auto (*function_to_do)( auto ) ) {
register unsigned int i=benchmark_repetitions;
register unsigned long long start=0;
my_time.reset();
start=__rdtsc();
while ( i-- ) {
auto result = (*function_to_do)( i << 7 );
#if USE_ASM_TO_PREVENT_ELIMINATION == 1
asm volatile("" :: "r"(
// There is no data type in C++ that is smaller than a char, so it will
// not throw a segmentation fault error to reinterpret any arbitrary
// data type as a char. Although, the compiler might not like it.
result
));
#endif
}
if ( function_name == nullptr ) {
empty_ticks = (__rdtsc()-start);
empty_seconds = my_time.elapsed();
std::cout<< "Empty:\n" << empty_ticks
<< " ticks\n" << benchmark_repetitions << " repetitions\n"
<< std::setprecision(15) << empty_seconds
<< " seconds\n\n";
} else {
std::cout<< function_name<<":\n" << (__rdtsc()-start-empty_ticks)
<< " ticks\n" << benchmark_repetitions << " repetitions\n"
<< std::setprecision(15) << (my_time.elapsed()-empty_seconds)
<< " seconds\n\n";
}
}
int main( void ) {
void* Cur_Thread= GetCurrentThread();
void* Cur_Process= GetCurrentProcess();
unsigned long long Current_Affinity;
unsigned long long System_Affinity;
unsigned long long furthest_affinity;
unsigned long long nearest_affinity;
if( ! SetThreadPriority(Cur_Thread,THREAD_PRIORITY_TIME_CRITICAL) ) {
SetThreadPriority( Cur_Thread, THREAD_PRIORITY_HIGHEST );
}
if( ! SetPriorityClass(Cur_Process,REALTIME_PRIORITY_CLASS) ) {
SetPriorityClass( Cur_Process, HIGH_PRIORITY_CLASS );
}
GetProcessAffinityMask( Cur_Process, &Current_Affinity, &System_Affinity );
furthest_affinity = 0x8000000000000000ULL>>__builtin_clzll(Current_Affinity);
nearest_affinity = 0x0000000000000001ULL<<__builtin_ctzll(Current_Affinity);
SetProcessAffinityMask( Cur_Process, furthest_affinity );
SetThreadAffinityMask( Cur_Thread, furthest_affinity );
const int repetitions=524288;
benchmark<repetitions>( nullptr, empty_function );
benchmark<repetitions>( "Standard Square Root", standard_sqrt );
benchmark<repetitions>( "Original Guess Square Root", original_guess_sqrt32 );
benchmark<repetitions>( "New Guess Square Root", new_guess_sqrt32 );
SetThreadPriority( Cur_Thread, THREAD_PRIORITY_IDLE );
SetPriorityClass( Cur_Process, IDLE_PRIORITY_CLASS );
SetProcessAffinityMask( Cur_Process, nearest_affinity );
SetThreadAffinityMask( Cur_Thread, nearest_affinity );
for (;;) { getchar(); }
return 0;
}
এছাড়াও, মাইক জার্ভিসকে তার টাইমারটির জন্য কৃতিত্ব।
দয়া করে নোট করুন (এটি অত্যন্ত গুরুত্বপূর্ণ) আপনি যদি বড় কোড স্নিপেটগুলি চালাচ্ছেন তবে আপনার কম্পিউটারকে জমাট বাঁধা রোধ করতে আপনার অবশ্যই পুনরাবৃত্তির সংখ্যাটি ফিরিয়ে আনতে হবে।