c++ - স্ট্যাক-মেমরির বরাদ্দের চেয়ে হিপ-মেমরির বরাদ্দ কেন বেশি দ্রুত হয়?




performance heap-memory (2)

আমি কোনটি আরও দ্রুত গতিতে দেখতে গাদা এবং স্ট্যাক মেমরির 10 ^ 7 পূর্ণসংখ্যার জন্য জায়গা বরাদ্দ করার চেষ্টা করেছি। স্পষ্টতই হিপ-মেমরির বরাদ্দ করা খুব দ্রুত ছিল তবে আমি কারণটি বুঝতে পারি না।

#include <bits/stdc++.h>
#include <chrono>

using namespace std;
using namespace std::chrono;

int main()
{
  high_resolution_clock::time_point t1 = high_resolution_clock::now();

  int *p = new int[1e7];

  high_resolution_clock::time_point t2 = high_resolution_clock::now();
  auto duration = duration_cast<microseconds>( t2 - t1 ).count();
  cout << duration / 1e6 << "\n"; // 5e-06



  t1 = high_resolution_clock::now();

  vector<int> v(1e7);

  t2 = high_resolution_clock::now();
  duration = duration_cast<microseconds>( t2 - t1 ).count();
  cout << duration / 1e6 << "\n"; // 0.112284

  return 0;
}

অন্যান্য উত্তরগুলি নির্দেশ করে যে ভেক্টর কনস্ট্রাক্টরে কমপক্ষে একটি "লুকানো" সূচনা রয়েছে।

তবে আপনার উদাহরণে আরও একটি সমস্যা রয়েছে: সম্ভবত এটি আপনি যা করেন তা মাপাও করে না। সি ++ তে অব্যবহৃত কোডটি বেঞ্চমার্কিং প্রায় অর্থহীন এবং সঠিকভাবে সময়সাপেক্ষী অনুকূলিতকরণ কোডটি শক্ত।

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

double test1() {
  high_resolution_clock::time_point t1 = high_resolution_clock::now();

  int *p = new int[1e7];

  high_resolution_clock::time_point t2 = high_resolution_clock::now();
  auto duration = duration_cast<microseconds>( t2 - t1 ).count();
  return duration / 1e6; // 5e-06
}

সংকলিত:

test1():                              # @test1()
        push    rbx
        call    std::chrono::_V2::system_clock::now()
        mov     rbx, rax
        call    std::chrono::_V2::system_clock::now()
        sub     rax, rbx
        movabs  rcx, 2361183241434822607
        imul    rcx
        mov     rax, rdx
        shr     rax, 63
        sar     rdx, 7
        add     rdx, rax
        cvtsi2sd        xmm0, rdx
        divsd   xmm0, qword ptr [rip + .LCPI0_0]
        pop     rbx
        ret
.LCPI1_0:
        .quad   4696837146684686336     # double 1.0E+6

প্রথম অংশ এমনকি অপারেটর নতুন কল না! সংকলক আপনার প্রোগ্রামটি দেখেছিল এবং বুঝতে পেরেছিল যে আপনি কখনই বরাদ্দকৃত অ্যারে ব্যবহার করেননি ফলে ফলশ্রুতিতে কার্যকর বরাদ্দ থেকে বরাদ্দ সরিয়ে দেওয়া হয়েছে।

সুতরাং আপনার প্রোগ্রামের প্রথম অংশটি পরিমাপকে অর্থহীন করে এমন সংস্থাগুলির সংকলন করার সময় গাদাতে বিন্যাস মোটেও বরাদ্দ দেয় না।

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


আমি কেবল একজন শিক্ষানবিস, তবে যা যা আমি বুঝতে পেরেছি তা মূলত নিজেকে পরীক্ষা করার জন্য আমাকে দেওয়া হোক।

মধ্যে

int *p = new int[1e7];

আপনি গাদা 10 মিলিয়ন পূর্ণসংখ্যার জন্য একটানা মেমরি বরাদ্দ করছেন।

মধ্যে

vector<int> v(1e7);

আপনি vector<int> অবজেক্টের জন্য স্ট্যাক মেমোরিতে বরাদ্দ দিচ্ছেন। এই অবজেক্টের সদস্যদের মধ্যে int[1e7] একটি int[1e7] পয়েন্টার রয়েছে, এটিও বরাদ্দ করা হয়। তদুপরি, এটিতে সমস্ত মান int() (0 এর সাথে int() এর মান দিয়ে শুরু করা হয়। std::vector কনস্ট্রাক্টর (2) দেখুন।






stack-memory