সি প্রোগ্রাম কার্যকর করার সময়


209

আমার একটি সি প্রোগ্রাম রয়েছে যা লক্ষ্য করে বেশ কয়েকটি প্রসেসরের সমান্তরালভাবে চালানো। আমার মৃত্যুদন্ড কার্যকর করার সময়টি রেকর্ড করতে সক্ষম হতে হবে (যা 1 সেকেন্ড থেকে কয়েক মিনিট পর্যন্ত যে কোনও জায়গায় হতে পারে)। আমি উত্তরগুলির সন্ধান করেছি, তবে তারা সকলেই clock()ফাংশনটি ব্যবহার করার পরামর্শ দিচ্ছে বলে মনে হচ্ছে , যার পরে প্রোগ্রামটি ঘড়িগুলির সংখ্যা গণনা করে যা Clocks_per_secondমান দ্বারা ভাগ করে নিয়েছে ।

আমি নিশ্চিত না যে কীভাবে Clocks_per_secondমূল্য গণনা করা হয়?

জাভাতে, আমি মৃত্যুদন্ড কার্যকর করার আগে এবং পরে কেবলমাত্র মিলিসেকেন্ডে বর্তমান সময় নিই।

সি তে কি একই জিনিস আছে? আমি একবার দেখেছি, তবে দ্বিতীয় রেজোলিউশনের চেয়ে ভাল কিছু পাওয়ার উপায় খুঁজে পাচ্ছি না।

আমি আরও সচেতন যে একজন প্রোফাইলার একটি বিকল্প হতে পারে তবে আমি নিজে একটি টাইমার প্রয়োগ করতে চাই।

ধন্যবাদ


3
আপনি কোন ওএস / এপিআই ফ্রেমওয়ার্কগুলি ব্যবহার করছেন / উপলভ্য? খালি সরল সি?
typo.pl

4
এটি একটি বরং ছোট প্রোগ্রাম, কেবল সরল সি
রজার

আমি এই উত্তরে একটি পোর্টেবল সমাধান প্রয়োগের বিষয়ে বিশদ লিখেছি: stackoverflow.com/questions/361363/…
আলেকজান্ডার সাপ্রিকিন

সময় সম্পূর্ণ ক্রিয়াকলাপ নির্বাহ করা নিয়ে যাওয়া stackoverflow.com/a/40380118/6180077
আব্দুল্লাহ Farweez

উত্তর:


344

CLOCKS_PER_SECএকটি ধ্রুবক যা ঘোষণা করা হয় <time.h>। সি অ্যাপ্লিকেশনটির মধ্যে কোনও টাস্কের সাহায্যে সিপিইউ সময় পেতে, ব্যবহার করুন:

clock_t begin = clock();

/* here, do your time-consuming job */

clock_t end = clock();
double time_spent = (double)(end - begin) / CLOCKS_PER_SEC;

নোট করুন যে এটি সময়কে ভাসমান পয়েন্টের ধরণের হিসাবে ফিরিয়ে দেয়। এটি এক সেকেন্ডের চেয়ে আরও সুনির্দিষ্ট হতে পারে (যেমন আপনি 4.52 সেকেন্ড পরিমাপ করেন)। যথার্থতা আর্কিটেকচারের উপর নির্ভর করে; আধুনিক সিস্টেমে আপনি সহজেই 10 মিমি বা তার চেয়ে কম পেতে পারেন তবে পুরানো উইন্ডোজ মেশিনে (উইন 98 যুগ থেকে) এটি 60 মিমি কাছাকাছি ছিল।

clock()মান সি; এটি "সর্বত্র" কাজ করে। getrusage()ইউনিক্স-এর মতো সিস্টেমে সিস্টেম-নির্দিষ্ট ফাংশন রয়েছে ।

জাভা System.currentTimeMillis()একই জিনিস পরিমাপ করে না। এটি একটি "প্রাচীরের ঘড়ি": এটি আপনাকে প্রোগ্রামটি কার্যকর করতে কত সময় লেগেছে তা মাপতে সহায়তা করতে পারে, তবে সিপিইউয়ের সময়টি কতটা ব্যবহৃত হয়েছিল তা আপনাকে জানায় না। মাল্টিটাস্কিং সিস্টেমে (অর্থাত্ এই সমস্ত) এগুলি বিস্তৃত হতে পারে।


1
এটি আমাকে খুব এলোমেলো ফলাফল দেয় - আমি একই কোডের টুকরোটির চেয়ে বড় / ছোট / নেতিবাচক সংখ্যার মিশ্রণ পাই। জিসিসি 4.7 লিনাক্স 3.2 এএমডি 64

3
হ্যাঁ: clock()"ঘড়ি" নামক কিছু অভ্যন্তরীণ স্কেলে একটি সময় ফেরত দেয় এবং CLOCKS_PER_SECএটি প্রতি সেকেন্ডের মধ্যে থাকা ঘড়ির সংখ্যা, তাই CLOCKS_PER_SECকয়েক সেকেন্ডের মধ্যে ফলন করে ভাগ করে । উপরের কোডে, মানটি এমন একটি doubleযাতে আপনি ইচ্ছামত স্কেল করতে পারেন।
টমাস পর্নিন

18
বড় সতর্কতা: ঘড়ি () ওএস আপনার প্রসেসটি চালাতে যে সময় ব্যয় করেছিল, তার প্রকৃত সময় কেটে যায় না তা ফিরিয়ে দেয়। যাইহোক, কোডের একটি ব্লকের সময় নির্ধারণের জন্য এটি সূক্ষ্ম, তবে বাস্তব বিশ্বে সময় কাটাতে মাপেনি।

2
তিনি বলেছিলেন যে তিনি একটি বহু-থ্রেড প্রোগ্রাম পরিমাপ করতে চান। আমি নিশ্চিত নই যে এর জন্য একটি ঘড়ি () উপযুক্ত, কারণ এটি সমস্ত থ্রেডের চলমান সময়গুলির সমষ্টি করে, সুতরাং ফলাফলটি দেখে মনে হবে যে কোডটি ধারাবাহিকভাবে চালিত হয়েছিল। এই জাতীয় জিনিসের জন্য আমি omp_get_wime () ব্যবহার করি তবে অবশ্যই আমার নিশ্চিত হওয়া দরকার যে সিস্টেমটি অন্যান্য প্রক্রিয়াতে ব্যস্ত নয়।
Youda008

1
আমার কিছু বিষয় উল্লেখ করা উচিত যদিও এক বছর আগে এই থ্রেডটি আরও প্রাসঙ্গিক ছিল: মান সহকারে এটি CLOCKS_PER_SECএকটি , বিভক্ত না হয়ে মাইক্রোসেকেন্ডে সময় দেওয়া; সিপিইউ ক্লক চক্র নয়। অতএব, এটিকে গতিশীল ফ্রিকোয়েন্সি হিসাবে গ্রহণ করার প্রয়োজন নেই কারণ এখানে ঘড়িটি মাইক্রোসেকেন্ডে রয়েছে (সম্ভবত 1 মেগাহার্টজ সিপিইউর জন্য ঘড়ির চক্র?) আমি একটি ছোট সি প্রোগ্রামটি মুদ্রণ করেছি এবং এটি আমার i7-2640M ল্যাপটপে 1000000 ছিল, গতিশীল ফ্রিকোয়েন্সি সহ 800 মেগাহার্টজকে 2.8 গিগাহার্জ-তে এমনকি টার্বো বুস্ট ব্যবহার করে 3.5 গিগাহার্জ-এর উচ্চতা ছাড়িয়ে যায়। long int1000000
DDPWNAGE

111

আপনি যদি দৌড়ানোর জন্য ইউনিক্স শেল ব্যবহার করে থাকেন তবে আপনি টাইম কমান্ডটি ব্যবহার করতে পারেন।

করছেন

$ time ./a.out

এক্স.কে এক্সিকিউটেবল হিসাবে ধরে নেওয়া এটি চালানোর জন্য আপনাকে সময় দেবে


3
@acgtyrant তবে কেবল সাধারণ প্রোগ্রামগুলির জন্য, কারণ এতে ইনপুট, আউটপুট ইত্যাদিসহ পুরো প্রোগ্রামটি সময় লাগবে
ফুচলভি

1
যদি আপনি লিনাক্সে থাকেন এবং আপনি নিজের (মাইক্রো) বেঞ্চমার্ককে উপেক্ষাযোগ্য স্টার্টআপ ওভারহেড সহ কোনও প্রোগ্রামে হ্রাস করেছেন, উদাহরণস্বরূপ একটি স্ট্যাটিক এক্সিকিউটেবল যা আপনার হট লুপটি কয়েক সেকেন্ডের জন্য চালায়, আপনি perf stat ./a.outক্যাশে মিসের জন্য এইচডব্লু পারফরম্যান্স কাউন্টার পেতে ব্যবহার করতে পারেন এবং শাখার ভুল ধারণা এবং আইপিসি।
পিটার কর্ডেস

61

সরল ভ্যানিলা সিতে:

#include <time.h>
#include <stdio.h>

int main()
{
    clock_t tic = clock();

    my_expensive_function_which_can_spawn_threads();

    clock_t toc = clock();

    printf("Elapsed: %f seconds\n", (double)(toc - tic) / CLOCKS_PER_SEC);

    return 0;
}

6
আমি কিছুক্ষণের মধ্যে দেখেছি সেরা পরিবর্তনশীল নাম। টিক = "ঘড়ির সময়", টোক = "টাইম আউট ক্লক"। তবে টিক-টোক = "টিক-টোক"। এইভাবেই আমি এখান থেকে সময় কেড়ে নিই।
লোগান শেল্লি

60

আপনি কার্যকরীভাবে এটি চান:

#include <sys/time.h>

struct timeval  tv1, tv2;
gettimeofday(&tv1, NULL);
/* stuff to do! */
gettimeofday(&tv2, NULL);

printf ("Total time = %f seconds\n",
         (double) (tv2.tv_usec - tv1.tv_usec) / 1000000 +
         (double) (tv2.tv_sec - tv1.tv_sec));

নোট করুন যে এই ব্যবস্থাগুলি মাইক্রোসেকেন্ডগুলিতে, কেবল কয়েক সেকেন্ড নয়।


2
MinGW সংকলকটি জিসি ভিত্তিক। সুতরাং এটি এটিতে কাজ করবে। তবে আপনি যদি ভিজ্যুয়াল সি সংকলক ব্যবহার করেন তবে আপনি ত্রুটি পাবেন।
ব্যবহারকারী 2550754

11
হ্যাঁ, এটি এসি লাইব্রেরি সহ উইন্ডোগুলিতে কাজ করবে যা গেটটাইমডে কল সমর্থন করে। সংকলকটি আসলে কী তা বোঝায় না, আপনাকে কেবল এটি একটি শালীন libc লাইব্রেরির সাথে লিঙ্ক করতে হবে। যা, মিংডব্লিউর ক্ষেত্রে, এটি ডিফল্ট উইন্ডো নয়।
ওয়েস হার্ডকার

1
এটি সাইগউইন জিসিসি এবং লিনাক্স উবুন্টু সহ উইন্ডোজ এক্সপিতে আমার জন্য কাজ করে। এটাই আমি চেয়েছিলাম।
প্রেম এবং শান্তি - জো কোডসওল

gettimeofdayঅপ্রচলিত এবং নতুন কোডের জন্য প্রস্তাবিত নয়। এর পসিক্স ম্যান পৃষ্ঠাটি তার পরিবর্তে ক্লক_জেটটাইম প্রস্তাবিত করে, যা আপনাকে এটির জন্য জিজ্ঞাসা করতে দেয় যা CLOCK_MONOTONICসিস্টেমের ঘড়ির পরিবর্তনের ফলে প্রভাবিত হয় না এবং এভাবে অন্তর সময়ের হিসাবে এটি আরও ভাল। ( জনসেলের উত্তর দেখুন )। আধুনিক লিনাক্স সিস্টেমে, উদাহরণস্বরূপ, গেটটাইমডেডি মূলত ক্লক_জেটটাইমের জন্য একটি মোড়ক যা ন্যানোসেকেন্ডগুলিকে মাইক্রোসেকেন্ডে রূপান্তর করে।
পিটার কর্ডেস

12

বেশিরভাগ সাধারণ প্রোগ্রামের মিলি-সেকেন্ডে গণনার সময় থাকে। সুতরাং, আমি মনে করি, আপনি এটি দরকারী পাবেন।

#include <time.h>
#include <stdio.h>

int main(){
    clock_t start = clock();
    // Execuatable code
    clock_t stop = clock();
    double elapsed = (double)(stop - start) * 1000.0 / CLOCKS_PER_SEC;
    printf("Time elapsed in ms: %f", elapsed);
}

আপনি যদি পুরো প্রোগ্রামটির রানটাইম গণনা করতে চান এবং আপনি ইউনিক্স সিস্টেমে থাকেন তবে টাইম কমান্ডটি এভাবে ব্যবহার করে আপনার প্রোগ্রামটি চালানtime ./a.out


উইন্ডোজটিতে কমপক্ষে ফ্যাক্টরটি কমপক্ষে 100 তবে 1000 নয় এবং এটি সঠিক নয়
বোকটুলাস

6
এই উত্তরটি এমন কোনও কিছু যুক্ত করে না যা দু'বছরের আগের থেকে আলেকজান্দ্রি সি -এর উত্তরে ছিল না ।
জোনাথন লেফলার

3
@ বোকটুলাস: উইন্ডোজগুলিতেও সর্বদা 1000 মিমি থাকে।
alk

9

অনেক উত্তর প্রস্তাব clock()এবং তারপর CLOCKS_PER_SECথেকে দেওয়া হয়েছে time.h। এটি সম্ভবত একটি খারাপ ধারণা, কারণ আমার /bits/time.hফাইলটি এটি বলে:

/* ISO/IEC 9899:1990 7.12.1: <time.h>
The macro `CLOCKS_PER_SEC' is the number per second of the value
returned by the `clock' function. */
/* CAE XSH, Issue 4, Version 2: <time.h>
The value of CLOCKS_PER_SEC is required to be 1 million on all
XSI-conformant systems. */
#  define CLOCKS_PER_SEC  1000000l

#  if !defined __STRICT_ANSI__ && !defined __USE_XOPEN2K
/* Even though CLOCKS_PER_SEC has such a strange value CLK_TCK
presents the real value for clock ticks per second for the system.  */
#   include <bits/types.h>
extern long int __sysconf (int);
#   define CLK_TCK ((__clock_t) __sysconf (2))  /* 2 is _SC_CLK_TCK */
#  endif

তাই CLOCKS_PER_SECআপনি সংকলনের জন্য কোন বিকল্পগুলি ব্যবহার করেন তার উপর নির্ভর করে 1000000 হিসাবে সংজ্ঞায়িত হতে পারে এবং এটি কোনও ভাল সমাধানের মতো বলে মনে হয় না।


1
তথ্যের জন্য ধন্যবাদ তবে এর পরেও এর চেয়ে ভাল আর কোন বিকল্প আছে কি?
ওজনমুয়েস

4
এটি কোনও প্রাকৃতিক সমস্যা নয়: হ্যাঁ পসিক্স সিস্টেমগুলি সর্বদা থাকে CLOCK_PER_SEC==1000000তবে একই সময়ে, তারা সকলেই তাদের ঘড়ির () প্রয়োগের জন্য 1-prec নির্ভুলতা ব্যবহার করে; যাইহোক, ভাগ করার সমস্যা হ্রাস করার জন্য এটিতে দুর্দান্ত সম্পত্তি রয়েছে। যদি আপনি সম্ভাব্য খুব দ্রুত ইভেন্টগুলি পরিমাপ করতে চান তবে 1 এমএসের নীচে বলুন, তবে আপনাকে প্রথমে ঘড়ির () ফাংশনের যথার্থতা (বা রেজোলিউশন) সম্পর্কে চিন্তা করা উচিত, যা পজিক্সে 1µ এর চেয়ে বেশি প্রয়োজন, তবে প্রায়শই অনেক বেশি মোটা হয়; সাধারণ সমাধানটি হচ্ছে পরীক্ষাটি বহুবার চালানো; জিজ্ঞাসা করা প্রশ্নটি যদিও এটির প্রয়োজন বলে মনে হচ্ছে না।
এন্টোইনএল

কেন এটি একটি ভাল সমাধান হবে না? আপনি কিছু মূল্য পেতে clock()পারেন, যদি আপনি সেই মানটি আপনার সাথে ভাগ করে CLOCK_PER_SECনেন তবে সিপিইউ সেকেন্ডের মধ্যে সময় পাওয়ার গ্যারান্টিযুক্ত। আসল ঘড়ির গতি পরিমাপের দায়িত্ব clock()ফাংশনের দায়িত্ব , আপনার নয়।
জাফি

9

ম্যাক্রো হিসাবে থমাস পর্নিনের উত্তর:

#define TICK(X) clock_t X = clock()
#define TOCK(X) printf("time %s: %g sec.\n", (#X), (double)(clock() - (X)) / CLOCKS_PER_SEC)

এটি এর মতো ব্যবহার করুন:

TICK(TIME_A);
functionA();
TOCK(TIME_A);

TICK(TIME_B);
functionB();
TOCK(TIME_B);

আউটপুট:

time TIME_A: 0.001652 sec.
time TIME_B: 0.004028 sec.

4

আপনার বিবেচনায় রাখতে হবে যে একটি প্রোগ্রাম কার্যকর করতে যে সময় লাগছিল তা পরিমাপ করা সেই নির্দিষ্ট মুহুর্তে মেশিনের বোঝাটির উপর অনেক বেশি নির্ভর করে।

এটি জেনে যে, সি তে বর্তমান সময় প্রাপ্তির উপায়টি বিভিন্ন উপায়ে অর্জিত হতে পারে, একটি সহজ কাজটি হ'ল:

#include <time.h>

#define CPU_TIME (getrusage(RUSAGE_SELF,&ruse), ruse.ru_utime.tv_sec + \
  ruse.ru_stime.tv_sec + 1e-6 * \
  (ruse.ru_utime.tv_usec + ruse.ru_stime.tv_usec))

int main(void) {
    time_t start, end;
    double first, second;

    // Save user and CPU start time
    time(&start);
    first = CPU_TIME;

    // Perform operations
    ...

    // Save end time
    time(&end);
    second = CPU_TIME;

    printf("cpu  : %.2f secs\n", second - first); 
    printf("user : %d secs\n", (int)(end - start));
}

আশা করি এটা সাহায্য করবে.

শুভেচ্ছা সহ!


4

(এখানে যদি আপনার সিসাদমিন সিস্টেমটাইম পরিবর্তন করে, বা আপনার টাইমজোন শীতকালে এবং স্মরক-সময়গুলির চেয়ে আলাদা হয় তবে এখানে সমস্ত উত্তরের অভাব রয়েছে Therefore তাই ...)

লিনাক্স ব্যবহারের ক্ষেত্রে: clock_gettime(CLOCK_MONOTONIC_RAW, &time_variable); সিস্টেম-অ্যাডমিন সময় পরিবর্তন করে বা গ্রীষ্মকালীন সময়ের চেয়ে শীতকালীন সময়ে এমন কোনও দেশে বাস করেন তবে এটি প্রভাবিত হয় না It's

#include <stdio.h>
#include <time.h>

#include <unistd.h> /* for sleep() */

int main() {
    struct timespec begin, end;
    clock_gettime(CLOCK_MONOTONIC_RAW, &begin);

    sleep(1);      // waste some time

    clock_gettime(CLOCK_MONOTONIC_RAW, &end);

    printf ("Total time = %f seconds\n",
            (end.tv_nsec - begin.tv_nsec) / 1000000000.0 +
            (end.tv_sec  - begin.tv_sec));

}

man clock_gettime পদ বলে:

CLOCK_MONOTONIC
              Clock  that  cannot  be set and represents monotonic time since some unspecified starting point.  This clock is not affected by discontinuous jumps in the system time
              (e.g., if the system administrator manually changes the clock), but is affected by the incremental adjustments performed by adjtime(3) and NTP.

আপনি যে সেকেন্ডটি সেকেন্ডের সংখ্যাটি পেয়েছিলেন তা কি ব্যাখ্যা করতে পারবেন? কী চলছে তা স্পষ্ট নয়।
কলিন কেইনান

1
এই (end.tv_nsec - begin.tv_nsec) / 1000000000.0ফলাফল কি 0সবসময় হবে না ?
ALK

@ ডাল: না, একটি doubleআক্ষরিক দ্বারা বিভাজক দ্বারা পূর্বে বা বিভাগের আগে রূপান্তর longকরতে পারে । অবশ্যই আপনি কেবল পূর্ণসংখ্যায় লেগে থাকতে পারেন এবং অংশটি মুদ্রণ করতে পারেন এবং তারপরে শূন্যের মতো ভগ্নাংশের অংশটি দ্বিগুণে রূপান্তর করা সহজ এবং 53 বিট নির্ভুলতা সাধারণত বেঞ্চমার্ক সময়ের জন্য প্রচুর। doubletv_sec%ld.%09ld
পিটার কর্ডেস

1
(ওফস, ন্যানোসেকেন্ডস অংশের বিয়োগের জন্য সেকেন্ডের অংশটি বহন করতে হতে পারে, তাই ডাবল ব্যবহার করা এবং এটিকে নেতিবাচক হতে দেওয়া সমস্যাটি এড়াতে পারে a খাঁটি পূর্ণসংখ্যার বিন্যাসের স্ট্রিংটি ব্যবহার করার জন্য, আপনার গ্লিবিসি ম্যানুয়ালটিতে প্রস্তাবিত timespec_subtractমত একটি প্রয়োজন timeval_subtract: gnu.org/software/libc/manual/html_node/lapsed-Time.html )
পিটার কর্ডস

3

এএনএসআই সি কেবলমাত্র দ্বিতীয় যথার্থ সময়ের ফাংশন নির্দিষ্ট করে। তবে, আপনি যদি পসিক্স পরিবেশে চলমান থাকেন তবে আপনি ইউনিক্স ইপোকের পর থেকে পাস হওয়া মাইক্রোসেকেন্ডস রেজোলিউশন সরবরাহকারী গেটটাইমডে () ফাংশনটি ব্যবহার করতে পারেন ।

পার্শ্ব নোট হিসাবে, আমি ঘড়ি ব্যবহার করার পরামর্শ দেব না (যেহেতু এটি অনেকগুলি (সমস্ত না?) সিস্টেমে খারাপভাবে প্রয়োগ করা হয়েছে এবং সঠিক নয়, এটি কেবলমাত্র আপনার প্রোগ্রাম সিপিইউতে কত দিন ব্যয় করেছে তা বোঝায় এবং প্রোগ্রামটির মোট জীবদ্দশায় নয়, যা আপনার প্রশ্ন অনুসারে আমি অনুমান করি যা আপনি পরিমাপ করতে চান।


আইএসও সি স্ট্যান্ডার্ড ( এএনএসআই সি এর অর্থ এটি ধরে নেওয়া) উদ্দেশ্যমূলকভাবে সময়ের কার্যকারিতার যথার্থতা নির্দিষ্ট করে না । তারপরে বিশেষত কোনও পসিক্স বাস্তবায়নের উপর, বা উইন্ডোজে দেয়াল-ঘড়ির যথার্থতা (থমাসের উত্তর দেখুন) সেকেন্ডে হয়। তবে ঘড়ির () স্পষ্টতা যথাযথভাবে বৃহত্তর হয় এবং সর্বদা পিক্সিতে (যথাযথভাবে স্বতন্ত্রভাবে
µ

2

প্রতিটি সমাধান আমার সিস্টেমে কাজ করছে না।

আমি ব্যবহার করতে পারেন

#include <time.h>

double difftime(time_t time1, time_t time0);

2
এটি time_tদ্বিগুণ হিসাবে দুটি মানের মধ্যে পার্থক্য দেয় । যেহেতু time_tমানগুলি কেবলমাত্র এক সেকেন্ডের সাথে নির্ভুল, তাই স্বল্প চলমান প্রোগ্রামগুলির দ্বারা সময় নির্ধারণের ক্ষেত্রে এটি সীমিত মানের হলেও এটি দীর্ঘ সময় ধরে চালিত প্রোগ্রামগুলির জন্য কার্যকর হতে পারে।
জোনাথন লেফলার

যে কারণেই হোক না কেন, একটি জোড়ের মধ্যে দিয়ে যাওয়া আমার কাছে সেকেন্ডের একশত ভাগের নির্ভুলতার জন্য কাজ clock_tকরে difftimeবলে মনে হচ্ছে। এটি লিনাক্স x86 এ রয়েছে। আমিও বিয়োগ পেতে পারে না stopএবং startকাজ।
ragerdl

@ ইরগারডল: difftime() clock() / CLOCKS_PER_SECসেকেন্ডে প্রত্যাশার সাথে সাথে আপনাকেও পাস করতে হবে।
ALK

2
    #include<time.h>
    #include<stdio.h>
    int main(){
clock_t begin=clock();

    int i;
for(i=0;i<100000;i++){
printf("%d",i);

}
clock_t end=clock();
printf("Time taken:%lf",(double)(end-begin)/CLOCKS_PER_SEC);
}

এই প্রোগ্রামটি কবজ মত কাজ করবে।


2

আমি দেখতে পেয়েছি যে সাধারণ ঘড়ি (), সবাই এখানে সুপারিশ করে, কোনও কারণে রান থেকে চালানো থেকে বঞ্চিতভাবে বিচ্যুত হয় এমনকি স্থির কোডের জন্য কোনও পার্শ্ব প্রতিক্রিয়া ছাড়াই, স্ক্রিনে আঁকানো বা ফাইল পড়ার মতো। এটি হতে পারে কারণ সিপিইউ বিদ্যুত ব্যবহারের পদ্ধতিগুলি পরিবর্তন করে, ওএস বিভিন্ন অগ্রাধিকার দেয় ইত্যাদি ইত্যাদি ...

সুতরাং প্রতিবার ঘড়ির সাথে বিশ্বস্ততার সাথে একই ফলাফল পাওয়ার একমাত্র উপায় হ'ল একাধিক বার লুপে (কয়েক মিনিটের জন্য) পরিমাপ করা কোডটি চালনা করা, সংযোজকটিকে এটির অপ্টিমাইজ করা থেকে বিরত রাখার জন্য সতর্কতা অবলম্বন করা: আধুনিক সংকলকরা কোডটিকে পূর্ববর্তী করতে পারে কোনও লুপে চলমান পার্শ্ব প্রতিক্রিয়া ছাড়াই এবং এটিকে লুপের বাইরে নিয়ে যান ie যেমন প্রতিটি পুনরুক্তির জন্য এলোমেলো ইনপুট ব্যবহার করা।

পর্যাপ্ত নমুনাগুলি একটি অ্যারেতে সংগ্রহ করার পরে, এক ধরণের যা অ্যারে হয় এবং মাঝারি উপাদানটিকে মধ্যস্থ বলে। মিডিয়ান গড়ের চেয়ে ভাল, কারণ এটি চরম বিচ্যুতিগুলি দূরে ফেলে দেয়, যেমন অ্যান্টিভাইরাস বলে যে সমস্ত সিপিইউ গ্রহণ করে বা ওএস কিছু আপডেট করে।

সি / সি ++ কোডের নির্বাহের পারফরম্যান্স পরিমাপের জন্য একটি সাধারণ ইউটিলিটি, মিডিয়ানের কাছাকাছি মানগুলির গড়: https://github.com/saniv/gauge

আমি নিজেও কোড পরিমাপের আরও শক্তিশালী এবং দ্রুততর উপায় খুঁজছি। কেউ সম্ভবত কোনও ওএস ছাড়াই বেয়ার ধাতব উপর নিয়ন্ত্রিত অবস্থায় কোড চালনার চেষ্টা করতে পারে তবে এটি অবাস্তব ফলাফল দেয় কারণ বাস্তবে ওএস জড়িত থাকে।

x86 এর এই হার্ডওয়্যার পারফরম্যান্স কাউন্টারগুলি রয়েছে, যার মধ্যে মৃত্যুদন্ড কার্যকর করার নির্দেশাবলীর প্রকৃত সংখ্যা অন্তর্ভুক্ত রয়েছে তবে তারা ওএস সহায়তা ছাড়াই অ্যাক্সেস করা জটিল, ব্যাখ্যা করার পক্ষে এবং তাদের নিজস্ব সমস্যা রয়েছে ( http://archive.gamedev.net/archive/references/articles /article213.html )। তবুও তারা বোতল ঘাড়ের প্রকৃতি (ডেটা অ্যাক্সেস বা সেই ডেটার উপর প্রকৃত গণনা) অনুসন্ধান করতে সহায়তা করতে পারে।


হ্যাঁ, আধুনিক x86 সিপিইউ সর্বাধিক টার্বোর তুলনায় অনেক ধীর। "গভর্নর" সেটিংসের উপর নির্ভর করে সর্বাধিক ঘড়ির গতিতে র‌্যাম্পটি মিলিসেকেন্ড (হার্ডওয়্যার পি-স্টেট ম্যানেজমেন্টের সাথে স্কাইলেক, বিশেষত এনার্জি-পারফরম্যান্স_প্রিফারেন্স সেট করা performance) বা অনেকগুলি দশ মাইলসেকেন্ড নিতে পারে । en.wikedia.org/wiki/ ডায়নামিক_ ফ্রিকোয়েন্সি_সেসালিং । এবং হ্যাঁ, মাঝারি পারফরম্যান্স সাধারণত একটি ভাল পছন্দ; উচ্চ প্রান্তে সাধারণত হস্তক্ষেপ থেকে কিছু স্পাইক থাকে।
পিটার

প্রায়শই কাজের অপ্টিমাইজ করা এড়াতে আপনার সেরা বাজি হ'ল কমান্ড-লাইন ইনপুট এবং ফলাফলটি ফিরে আসে। বা mainএটি থেকে একটি পৃথক ফাইলে একটি ফাংশন লিখুন যা একটি আরগ নেয় এবং ফলাফল দেয় এবং লিঙ্ক-টাইম অপ্টিমাইজেশন ব্যবহার করবেন না। তারপরে সংকলক এটি কলারের সাথে ইনলাইন করতে পারে না। যদি ফাংশনটিতে ইতিমধ্যে কিছু ধরণের লুপ অন্তর্ভুক্ত থাকে তবেই কাজ করে, অন্যথায় কল / রেট ওভারহেড খুব বেশি high
পিটার

আপনি যদি কোনও পার্শ্ব প্রতিক্রিয়া ছাড়াই স্থির কোড দিয়ে প্রক্রিয়া করেন তবে কম্পাইলারটি লুপের বাইরে একক কমান্ড লাইন ইনপুটটিকে অনুকূল করতে পারে। সুতরাং প্রতিটি পুনরাবৃত্তির জন্য একটি এলোমেলো ইনপুট উত্পন্ন করা ভাল। স্পষ্টতই র‌্যান্ড () প্রথম ঘড়ির আগে পরিমাপ করা কোডের বাইরে কল করা উচিত (), কারণ র‌্যান্ড () এর ফলে কিছু সিস্টেমের কল আসতে পারে, কিছু হার্ডওয়্যার এনট্রপি জেনারেটর (যা পুরানো সিস্টেমে মাউস মুভমেন্ট ছিল) স্যাম্পল করে। আউটপুটটির প্রতিটি বিট প্রিন্টফ করতে ভুলবেন না, অন্যথায় সংকলক সিদ্ধান্ত নিতে পারে আপনার পুরো আউটপুট পুরো বা এর অংশের দরকার নেই। সিআরসি 32 বলার মাধ্যমে এটি করা যেতে পারে।
স্মাগলিস্পউইনি

যদি আপনার কোড-আন্ডার-টেস্টটি একটি পৃথক ফাইলে প্রবেশ করে এবং আপনি লিঙ্ক-টাইম অপ্টিমাইজেশন ব্যবহার না করেন, তবে কলগুলির মধ্যে অপ্টিমাইজ করার জন্য সংকলক সিএসই করতে পারে এমন কোনও উপায় নেই। কলার কোনও দৃশ্যমান পার্শ্ব-প্রতিক্রিয়া না পেয়ে কলির সম্পর্কে কিছু ধরে নিতে পারে না। এই আপনি কিছু অপেক্ষাকৃত ছোট করা দেয় ভিতরে একটি পুনরাবৃত্ত লুপ এটা দীর্ঘ যথেষ্ট করতে সময় মাত্র কল / অবঃ ওভারহেড সঙ্গে। যদি আপনি এটিকে ইনলাইন করতে দেন, তবে আপনাকে যেভাবে বলা হবে তা কোনও লুপের বাইরে কোনও গণনা উত্তোলন করে না তা নিশ্চিত করার জন্য আপনাকে উত্পন্ন এএসএমটি পরীক্ষা করতে হবে।
পিটার

সংকলক-সুনির্দিষ্ট উপায়টি হ'ল GNU সি ইনলাইন এসেমটি কোনও সংকলককে একটি রেজিস্টারে ফল কার্যকর করতে বাধ্য করা এবং / অথবা ভেরিয়েবলের মান সম্পর্কে যা জানে তা ভুলে যাওয়া, অতিরিক্ত নির্দেশাবলী না দিয়েই। এমএসভিসিতে "এস্কেপ" এবং "ক্লোবার" সমতুল্য প্রোফাইলিং এবং মাইক্রোবেঞ্চমার্কিং সম্পর্কিত একটি ভিডিওর লিঙ্ক করে (ঝনঝন বিকাশকারী চ্যানডলার ক্যারথের সিপিসি 2015 টক) কোনও এমএসভিসি সমতুল্য নেই, তবে প্রশ্নটি নিজেই জিএনইউ সি ফাংশন এবং সেগুলি কীভাবে ব্যবহার করবে তা দেখায়।
পিটার

0

কারও কারও কাছে বিভিন্ন ধরণের ইনপুট দরকারী মনে হতে পারে: জিপিজিপিইউ-প্রোগ্রামিংয়ের একটি বিশ্ববিদ্যালয়ের কোর্সের অংশ হিসাবে আমাকে এনভিডিয়া সিইউডিএ ( কোর্সের বিবরণ ) সহ সময় নির্ধারণের এই পদ্ধতিটি দেওয়া হয়েছিল । এটি পূর্ববর্তী পোস্টগুলিতে দেখা পদ্ধতিগুলিকে একত্রিত করে এবং আমি কেবল এটি পোস্ট করি কারণ প্রয়োজনীয়তাগুলি এটি বিশ্বাসযোগ্যতা দেয়:

unsigned long int elapsed;
struct timeval t_start, t_end, t_diff;
gettimeofday(&t_start, NULL);

// perform computations ...

gettimeofday(&t_end, NULL);
timeval_subtract(&t_diff, &t_end, &t_start);
elapsed = (t_diff.tv_sec*1e6 + t_diff.tv_usec);
printf("GPU version runs in: %lu microsecs\n", elapsed);

আমি মনে করি আপনি যেমন 1.0 / 1000.0পরিমাপের এককটি পেতে পারেন যা আপনার প্রয়োজন অনুসারে গুন করতে পারে ।


1
gettimeofday অপ্রচলিত এবং প্রস্তাবিত নয়। clock_gettimeপরিবর্তে এর পসিক্স ম্যান পৃষ্ঠাটি সুপারিশ করে, যা আপনাকে এটির জন্য জিজ্ঞাসা করতে দেয় CLOCK_MONOTONICযে এটি সিস্টেমের ঘড়ির পরিবর্তনের দ্বারা প্রভাবিত হয় না এবং এভাবে অন্তর টাইমার হিসাবে এটি আরও ভাল। আধুনিক লিনাক্স সিস্টেমগুলিতে, উদাহরণস্বরূপ, gettimeofdayমূলত এমন একটি মোড়ক clock_gettimeযা ন্যানোসেকেন্ডগুলিকে মাইক্রোসেকেন্ডে রূপান্তর করে। (জনসেলের উত্তর দেখুন)।
পিটার কর্ডেস

এই পদ্ধতিটি @ ওয়েজ হার্ডার যোগ করেছেন, মূল পার্থক্যটি ব্যবহার করা হচ্ছে timeval_subtract
イ き ん ぐ

ঠিক আছে, সুতরাং আপনার উত্তরের একমাত্র দরকারী অংশটি এমন কোনও ফাংশনের নাম যা আপনি সংজ্ঞায়িত করেন না এবং এটি স্ট্যান্ডার্ড লাইব্রেরিতে নেই। (কেবলমাত্র গ্লিবিসি ম্যানুয়ালটিতে: gnu.org/software/libc/manual/html_node/Elapsed-Time.html )।
পিটার কর্ডেস

-2

বুদ্বুদ বাছাই এবং সিলেকশন সাজানোর কার্য সম্পাদনের সময়ের তুলনা আমার কাছে একটি প্রোগ্রাম রয়েছে যা বুদ্বুদ সাজানোর এবং নির্বাচনের বাছাইয়ের সম্পাদনের সময়কে তুলনা করে। কোডের কোনও ব্লকের কার্য সম্পাদনের সময়টি নির্ধারণের আগে এবং পরে ব্লকটির সময় গণনা করুন

 clock_t start=clock();
 
 clock_t end=clock();
 CLOCKS_PER_SEC is constant in time.h library

উদাহরণ কোড:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
   int a[10000],i,j,min,temp;
   for(i=0;i<10000;i++)
   {
      a[i]=rand()%10000;
   }
   //The bubble Sort
   clock_t start,end;
   start=clock();
   for(i=0;i<10000;i++)
   {
     for(j=i+1;j<10000;j++)
     {
       if(a[i]>a[j])
       {
         int temp=a[i];
         a[i]=a[j];
         a[j]=temp;
       }
     }
   }
   end=clock();
   double extime=(double) (end-start)/CLOCKS_PER_SEC;
   printf("\n\tExecution time for the bubble sort is %f seconds\n ",extime);

   for(i=0;i<10000;i++)
   {
     a[i]=rand()%10000;
   }
   clock_t start1,end1;
   start1=clock();
   // The Selection Sort
   for(i=0;i<10000;i++)
   {
     min=i;
     for(j=i+1;j<10000;j++)
     {
       if(a[min]>a[j])
       {
         min=j;
       }
     }
     temp=a[min];
     a[min]=a[i];
     a[i]=temp;
   }
   end1=clock();
   double extime1=(double) (end1-start1)/CLOCKS_PER_SEC;
   printf("\n");
   printf("\tExecution time for the selection sort is %f seconds\n\n", extime1);
   if(extime1<extime)
     printf("\tSelection sort is faster than Bubble sort by %f seconds\n\n", extime - extime1);
   else if(extime1>extime)
     printf("\tBubble sort is faster than Selection sort by %f seconds\n\n", extime1 - extime);
   else
     printf("\tBoth algorithms have the same execution time\n\n");
}

4
এই সত্যিই নতুন সঙ্গে তুলনা কিছু যোগ করে না adimoh এর উত্তর ছাড়া এতে পূরণ 'কিছু প্রকৃত কোড সহ এক্সিকিউটেবল কোড' ব্লক (অথবা তাদের দুটি)। এবং এই উত্তরটি এমন কোনও কিছু যুক্ত করে না যা আলেকজান্দ্রি সি এর জবাব দু'বছরের আগের থেকে ছিল না ।
জোনাথন লেফলার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.