Solidity

EVM 記憶體的成本如何擴展?

  • March 2, 2022

EVM 記憶體的成本如何擴展?

我想知道 EVM 記憶體(不是儲存)的成本如何擴展?

確實,在閱讀了其他 QA 之後,記憶體成本不是線性函式,而是應該隨著分配的更多而迅速增加?

在 Solidity 中編寫了 Floyd-Warshall 算法,該算法分配了一個 (nxn) 的 uint 矩陣,我發現氣體消耗增加得非常快。即使 n = 24 也是如此,其中氣體使用量約為 19085414。

pragma solidity ^0.4.11;

contract APSPBenchmark is usingOraclize {

   event OraclizeEvent0(string desc);        
   event OraclizeEvent1(string desc, int[] apsp);

   int constant INF = -1;

   function APSPBenchmark() public payable {}    

   /*
   * Local all-pairs shortest path
   */
   function localAPSP(int[] w) public {

       int[] memory apsp  = allPairsShortestPath(w);

       OraclizeEvent0("local");
       //OraclizeEvent1("local", apsp); // Infinity encoded as -1
   }

   /*
   * All-pairs shortest path
   */
   function allPairsShortestPath(int[] w) private constant returns(int[]) {
       uint i; uint j; uint k;
       uint n = babylonian(w.length);
       int[] memory d = new int[](n * n);

       for (i = 0; i < n; ++i) {
           for (j = 0; j < n; ++j) {
               d[i * n +j] = (w[i * n + j] >= 100 ? INF : w[i * n + j]);
           }   
           d[i * n + i] = 0;
       }

       for (k = 0; k < n; ++k) {
           for (i = 0; i < n; ++i) {
               for (j = 0; j < n; ++j) {
                   if (d[i * n + k] == INF || d[k * n + j] == INF) continue;
                   else if (d[i * n + j] == INF) d[i * n + j] = d[i * n + k] + d[k * n + j];
                   else d[i * n + j] = min(d[i * n +j], d[i * n + k] + d[k * n + j]);
               }
           }
       }

       return d;
   }

   /*
   * Minimum of two values
   */
   function min(int a, int b) private constant returns(int)  {
       return a < b ? a : b;
   }    

   /*
   * Babylonian sqrt 
   */
   function babylonian(uint n) private constant returns(uint) {
       uint x = n;
       uint y = 1;
       while (x > y) {
           x = (x + y) / 2;
           y = n / x;
       }
       return x;
   }
}

記憶體擴展的gas成本在黃皮書 附錄H中定義如下,

記憶體成本公式

G_memory 為 3,a是分配的 256 位字 ( ints) 的數量。

對於 a=24^2,等於 3 * 576 + 648 = 2,376。所以看起來記憶體成本不是你的主要問題。

這個答案中的公式實際上不是擴展成本,而是記憶體成本。

擴展成本是先前未觸及的記憶體字的額外記憶體成本。請參閱Solidity 文件並在下面從黃皮書的附錄 H中引用。

另請注意,Cmem 是記憶體成本函式(擴展函式是之前和之後成本之間的差異)。它是一個多項式,對高階係數進行除法和取底,因此線性使用高達 724B 的記憶體,之後它的成本要高得多。

(沒有足夠的代表發表評論)

引用自:https://ethereum.stackexchange.com/questions/29896