Difference between revisions of "Comparing Canister Cycles vs Performance Counter"

From Internet Computer Wiki
Jump to: navigation, search
(Created page with "This small example clarifies the Canister Cycles balance <code>ic0.canister_cycle_balance()</code> and Performance Counter <code>ic0.performance_counter()</code> for inter-can...")
 
m
 
(12 intermediate revisions by 2 users not shown)
Line 1: Line 1:
This small example clarifies the Canister Cycles balance <code>ic0.canister_cycle_balance()</code> and Performance Counter <code>ic0.performance_counter()</code> for inter-canister calls.
+
The example walks through a scenario of charging cycles that includes inter-canister calls and how the performance counter relates to the work done by canisters.
  
 
== Setup ==
 
== Setup ==
# There is a ''User'' and two Canisters: ''Canisters A'' and ''Canister B''
+
# Canisters ''A'' and ''B'' are on the same subnet.
 
# The ''User'' sends an 1KiB ''Ingress Message'' to ''Canister A''
 
# The ''User'' sends an 1KiB ''Ingress Message'' to ''Canister A''
 
# The ''Canister A'' calls ''Canister B'' with an 2KiB ''Update Call''
 
# The ''Canister A'' calls ''Canister B'' with an 2KiB ''Update Call''
# The ''Canister B'' replies to ''Canister A'' with an 300-byte response
+
# The ''Canister B'' responds to ''Canister A'' with an 300-byte reply
# The ''Canister A'' replies to ''User'' with an 500-byte response
+
# The ''Canister A'' responds to ''User'' with an 500-byte reply
  
 
== Example Cycles Flow ==
 
== Example Cycles Flow ==
Line 21: Line 21:
 
{| class="wikitable" style="text-align:right"
 
{| class="wikitable" style="text-align:right"
 
|-
 
|-
! What is Happening !! Canister A<br>Cycles Balance !! Canister A<br>Perf Counter !! Canister B<br>Cycles Balance !! Canister B<br>Perf Counter
+
!style=text-align:left| Example Step !! Canister A<br>Cycles Balance !! Canister A<br>Perf Counter !! Canister B<br>Cycles Balance !! Canister B<br>Perf Counter
 
|-
 
|-
 
|style=text-align:left| 1. Initial state || <code>1T</code> || <code>N/A</code><sup>1)</sup> || <code>1T</code> || <code>N/A</code><sup>1)</sup>
 
|style=text-align:left| 1. Initial state || <code>1T</code> || <code>N/A</code><sup>1)</sup> || <code>1T</code> || <code>N/A</code><sup>1)</sup>
Line 27: Line 27:
 
|style=text-align:left| 2. ''Canister A'' receives 1KiB ''Ingress Message'' || -1,2M<br>-1KiB*2K<br><code>≈999'996M</code> || <code>N/A</code><sup>1)</sup> || <code>1T</code> || <code>N/A</code><sup>1)</sup>
 
|style=text-align:left| 2. ''Canister A'' receives 1KiB ''Ingress Message'' || -1,2M<br>-1KiB*2K<br><code>≈999'996M</code> || <code>N/A</code><sup>1)</sup> || <code>1T</code> || <code>N/A</code><sup>1)</sup>
 
|-
 
|-
|style=text-align:left| 3. ''Canister A'' starts execution <sup>2)</sup> || -5B/10*4<br><code>≈997'996M</code> || <code>0</code><br>(5B limit) || <code>1T</code> || <code>N/A</code><sup>1)</sup>
+
|style=text-align:left| 3. ''Canister A'' starts execution <sup>2)</sup> || -590K<br>-5B/10*4<br><code>≈997'996M</code> || <code>0</code><br>(5B limit) || <code>1T</code> || <code>N/A</code><sup>1)</sup>
 
|-
 
|-
 
|style=text-align:left| 4. ''Canister A'' executes 100M WASM instructions || <code>997'996M</code> || +100M<br><code>=100M</code><br>(5B limit) || <code>1T</code> || <code>N/A</code><sup>1)</sup>
 
|style=text-align:left| 4. ''Canister A'' executes 100M WASM instructions || <code>997'996M</code> || +100M<br><code>=100M</code><br>(5B limit) || <code>1T</code> || <code>N/A</code><sup>1)</sup>
 
|-
 
|-
|style=text-align:left| 5. ''Canister A'' sends 2KiB call to ''Canister B'' <sup>3)</sup> || -260K<br>-2KiB*1K<br>-5B/10*4<br>-2MiB*1K<br><code>≈993'897M</code> || +3*20<br>+1KiB<br><code>≈100M</code><br>(5B limit) || <code>1T</code> || <code>N/A</code><sup>1)</sup>
+
|style=text-align:left| 5. ''Canister A'' sends 2KiB call to ''Canister B'' <sup>3)</sup> || -260K<br>-2KiB*1K<br>-2MiB*1K<br>-590K<br>-5B/10*4<br><code>≈993'897M</code> || +3*21<sup>7)</sup><br>+2KiB<br><code>≈100M</code><br>(5B limit) ||<code>1T</code> || <code>N/A</code><sup>1)</sup>
 
|-
 
|-
|style=text-align:left| 5. ''Canister A'' finishes execution <sup>4)</sup> || +(5B-100M)*4/10<br><code>≈995'857M</code> || <code>N/A</code><sup>1)</sup> || <code>1T</code> || <code>N/A</code><sup>1)</sup>
+
|style=text-align:left| 6. ''Canister A'' finishes execution <sup>4)</sup> || +(5B-100M)*4/10<br><code>≈995'857M</code> || <code>N/A</code><sup>1)</sup> || <code>1T</code> || <code>N/A</code><sup>1)</sup>
 
|-
 
|-
|style=text-align:left| 6. ''Canister B'' receives a call from ''Canister A'' || <code>995'857M</code> || <code>N/A</code><sup>1)</sup> || -590K<br><code>≈999'999M</code> || <code>N/A</code><sup>1)</sup>
+
|style=text-align:left| 7. ''Canister B'' starts execution <sup>2)</sup>|| <code>995'857M</code> || <code>N/A</code><sup>1)</sup> || -590K<br>-5B/10*4<br><code>≈997'999M</code> || <code>0</code><br>(5B limit)
|-
 
|style=text-align:left| 7. ''Canister B'' starts execution <sup>2)</sup>|| <code>995'857M</code> || <code>N/A</code><sup>1)</sup> || -5B/10*4<br><code>≈997'999M</code> || <code>0</code><br>(5B limit)
 
 
|-
 
|-
 
|style=text-align:left| 8. ''Canister B'' executes 100M WASM instructions || <code>995'857M</code> || <code>N/A</code><sup>1)</sup> || <code>997'999M</code> || +100M<br><code>=100M</code><br>(5B limit)
 
|style=text-align:left| 8. ''Canister B'' executes 100M WASM instructions || <code>995'857M</code> || <code>N/A</code><sup>1)</sup> || <code>997'999M</code> || +100M<br><code>=100M</code><br>(5B limit)
 
|-
 
|-
|style=text-align:left| 9. ''Canister B'' sends 300-byte response to ''Canister A'' || <code>995'857M</code> || <code>N/A</code><sup>1)</sup> || <code>997'999M</code> || +2*20<br>+300<br><code>≈100M</code><br>(5B limit)
+
|style=text-align:left| 9. ''Canister B'' sends 300-byte reply to ''Canister A'' || <code>995'857M</code> || <code>N/A</code><sup>1)</sup> || <code>997'999M</code> || +2*21<sup>7)</sup><br>+300<br><code>≈100M</code><br>(5B limit)
 
|-
 
|-
 
|style=text-align:left| 10. ''Canister B'' finishes execution <sup>4)</sup> || <code>995'857M</code> || <code>N/A</code><sup>1)</sup> || +(5B-100M)*4/10<br><code>≈999'959M</code> || <code>N/A</code><sup>1)</sup>
 
|style=text-align:left| 10. ''Canister B'' finishes execution <sup>4)</sup> || <code>995'857M</code> || <code>N/A</code><sup>1)</sup> || +(5B-100M)*4/10<br><code>≈999'959M</code> || <code>N/A</code><sup>1)</sup>
 
|-
 
|-
|style=text-align:left| 11. ''Canister A'' receives a response from ''Canister B'' <sup>5)</sup> || +(2MiB-300)*1K<br><code>≈997'953M</code> || <code>N/A</code><sup>1)</sup> || <code>999'959M</code> || <code>N/A</code><sup>1)</sup>
+
|style=text-align:left| 11. ''Canister A'' receives a reply from ''Canister B'' <sup>5)</sup> || +(2MiB-300)*1K<br><code>≈997'953M</code> || <code>N/A</code><sup>1)</sup> || <code>999'959M</code> || <code>N/A</code><sup>1)</sup>
 
|-
 
|-
 
|style=text-align:left| 12. ''Canister A'' starts reply callback execution <sup>6)</sup> || <code>997'953M</code> || <code>0</code><br>(5B limit)  || <code>999'959M</code> || <code>N/A</code><sup>1)</sup>
 
|style=text-align:left| 12. ''Canister A'' starts reply callback execution <sup>6)</sup> || <code>997'953M</code> || <code>0</code><br>(5B limit)  || <code>999'959M</code> || <code>N/A</code><sup>1)</sup>
Line 51: Line 49:
 
|style=text-align:left| 13. ''Canister A'' executes 100M WASM instructions || <code>997'953M</code> || +100M<br><code>=100M</code><br>(5B limit) || <code>999'959M</code> || <code>N/A</code><sup>1)</sup>
 
|style=text-align:left| 13. ''Canister A'' executes 100M WASM instructions || <code>997'953M</code> || +100M<br><code>=100M</code><br>(5B limit) || <code>999'959M</code> || <code>N/A</code><sup>1)</sup>
 
|-
 
|-
|style=text-align:left| 14. ''Canister A'' sends 500-byte reply to ''User'' || <code>997'953M</code> || +2*20<br>+500<br><code>≈100M</code><br>(5B limit) || <code>999'959M</code> || <code>N/A</code><sup>1)</sup>
+
|style=text-align:left| 14. ''Canister A'' sends 500-byte reply to ''User'' || <code>997'953M</code> || +2*21<br>+500<br><code>≈100M</code><br>(5B limit) || <code>999'959M</code> || <code>N/A</code><sup>1)</sup>
 
|-
 
|-
 
|style=text-align:left| 15. ''Canister A'' finishes execution <sup>4)</sup> || +(5B-100M)*4/10<br><code>≈999'913M</code> || <code>N/A</code><sup>1)</sup> || <code>999'959M</code> || <code>N/A</code><sup>1)</sup>
 
|style=text-align:left| 15. ''Canister A'' finishes execution <sup>4)</sup> || +(5B-100M)*4/10<br><code>≈999'913M</code> || <code>N/A</code><sup>1)</sup> || <code>999'959M</code> || <code>N/A</code><sup>1)</sup>
 
|-
 
|-
!style=text-align:left| Total Cycles Spent: !! <code>87M</code> !!  !! <code>41M</code> !!
+
!style=text-align:left| Total: !! <code>~87M Cycles</code><br>for ~200M WASM Instructions Executed<br>+ messaging !!  !! <code>~41M Cycles</code><br>for ~100M WASM Instructions Executed<br>+ messaging !!
 
|}
 
|}
  
Line 61: Line 59:
 
'''Notes:'''
 
'''Notes:'''
 
# The ''Performance Counter'' is available only during execution, so it's marked as <code>N/A</code> when the execution has not started yet.
 
# The ''Performance Counter'' is available only during execution, so it's marked as <code>N/A</code> when the execution has not started yet.
# At the moment, there is a 5B instructions limit per normal message execution, so the Canister get charged for the maximum amount of Instructions it can potentially execute.
 
 
# The Canister get charged:
 
# The Canister get charged:
#; 260'000 : for the inter-canister call
+
#; 590K : for the update message execution
#; 2KiB * 1'000 : for byte transmission
+
#; 5B/10*4 : for 5B instructions it can potentially execute
#; 5B/10*4 : for 5B instructions limit to process the response
+
# The Canister get charged:
#; 2MiB * 1K : for the maximum response size
+
#; 260K : for the inter-canister call
 +
#; 2KiB * 1K : for byte transmission
 +
#; 2MiB * 1K : for the maximum reply size
 +
#; 590K : for the reply update message execution
 +
#; 5B/10*4 : for 5B instructions limit it can potentially execute in the reply handler
 
# The Canister gets a refund for the unused Instructions.
 
# The Canister gets a refund for the unused Instructions.
# The Canister gets a refund for the unused response bytes.
+
# The Canister gets a refund for the unused reply bytes.
# The Canister has already been charged for the reply callback.
+
# The Canister has already been charged in step 5 for the reply execution and 5B instructions.
 +
# The <code>n*21</code> represents System API calls costs.
  
 
== References ==
 
== References ==
# [https://smartcontracts.org/docs/current/references/ic-interface-spec The Internet Computer Interface Specification]
+
# [https://internetcomputer.org/docs/current/references/ic-interface-spec The Internet Computer Interface Specification]
# [https://smartcontracts.org/docs/current/developer-docs/updates/computation-and-storage-costs The Internet Computer Computation and Storage Costs]
+
# [https://internetcomputer.org/docs/current/developer-docs/deploy/computation-and-storage-costs The Internet Computer Computation and Storage Costs]
 
# [https://www.youtube.com/watch?v=YL4R4jQ78u0 Community Conversations | Charging Canister Cycles]
 
# [https://www.youtube.com/watch?v=YL4R4jQ78u0 Community Conversations | Charging Canister Cycles]

Latest revision as of 19:37, 16 August 2023

The example walks through a scenario of charging cycles that includes inter-canister calls and how the performance counter relates to the work done by canisters.

Setup

  1. Canisters A and B are on the same subnet.
  2. The User sends an 1KiB Ingress Message to Canister A
  3. The Canister A calls Canister B with an 2KiB Update Call
  4. The Canister B responds to Canister A with an 300-byte reply
  5. The Canister A responds to User with an 500-byte reply

Example Cycles Flow

Naming conventions:

  • 1K == 1'000
  • 1KiB == 1'024 bytes
  • 1M == 1'000'000
  • 1MiB == 1'048'576 bytes
  • 1B == 1'000'000'000
  • 1T == 1'000'000'000'000
Example Step Canister A
Cycles Balance
Canister A
Perf Counter
Canister B
Cycles Balance
Canister B
Perf Counter
1. Initial state 1T N/A1) 1T N/A1)
2. Canister A receives 1KiB Ingress Message -1,2M
-1KiB*2K
≈999'996M
N/A1) 1T N/A1)
3. Canister A starts execution 2) -590K
-5B/10*4
≈997'996M
0
(5B limit)
1T N/A1)
4. Canister A executes 100M WASM instructions 997'996M +100M
=100M
(5B limit)
1T N/A1)
5. Canister A sends 2KiB call to Canister B 3) -260K
-2KiB*1K
-2MiB*1K
-590K
-5B/10*4
≈993'897M
+3*217)
+2KiB
≈100M
(5B limit)
1T N/A1)
6. Canister A finishes execution 4) +(5B-100M)*4/10
≈995'857M
N/A1) 1T N/A1)
7. Canister B starts execution 2) 995'857M N/A1) -590K
-5B/10*4
≈997'999M
0
(5B limit)
8. Canister B executes 100M WASM instructions 995'857M N/A1) 997'999M +100M
=100M
(5B limit)
9. Canister B sends 300-byte reply to Canister A 995'857M N/A1) 997'999M +2*217)
+300
≈100M
(5B limit)
10. Canister B finishes execution 4) 995'857M N/A1) +(5B-100M)*4/10
≈999'959M
N/A1)
11. Canister A receives a reply from Canister B 5) +(2MiB-300)*1K
≈997'953M
N/A1) 999'959M N/A1)
12. Canister A starts reply callback execution 6) 997'953M 0
(5B limit)
999'959M N/A1)
13. Canister A executes 100M WASM instructions 997'953M +100M
=100M
(5B limit)
999'959M N/A1)
14. Canister A sends 500-byte reply to User 997'953M +2*21
+500
≈100M
(5B limit)
999'959M N/A1)
15. Canister A finishes execution 4) +(5B-100M)*4/10
≈999'913M
N/A1) 999'959M N/A1)
Total: ~87M Cycles
for ~200M WASM Instructions Executed
+ messaging
~41M Cycles
for ~100M WASM Instructions Executed
+ messaging


Notes:

  1. The Performance Counter is available only during execution, so it's marked as N/A when the execution has not started yet.
  2. The Canister get charged:
    590K
    for the update message execution
    5B/10*4
    for 5B instructions it can potentially execute
  3. The Canister get charged:
    260K
    for the inter-canister call
    2KiB * 1K
    for byte transmission
    2MiB * 1K
    for the maximum reply size
    590K
    for the reply update message execution
    5B/10*4
    for 5B instructions limit it can potentially execute in the reply handler
  4. The Canister gets a refund for the unused Instructions.
  5. The Canister gets a refund for the unused reply bytes.
  6. The Canister has already been charged in step 5 for the reply execution and 5B instructions.
  7. The n*21 represents System API calls costs.

References

  1. The Internet Computer Interface Specification
  2. The Internet Computer Computation and Storage Costs
  3. Community Conversations | Charging Canister Cycles