   return ESP.getCycleCount() - b;
 }
 
+uint32_t cyclesToRead_nKxs16(int n, short *x, int32_t *res) {
+  uint32_t b = ESP.getCycleCount();
+  int32_t sum = 0;
+  for (int i = 0; i < n * 1024; i++) {
+    sum += *(x++);
+  }
+  *res = sum;
+  return ESP.getCycleCount() - b;
+}
+
+uint32_t cyclesToWrite_nKxs16(int n, short *x) {
+  uint32_t b = ESP.getCycleCount();
+  int32_t sum = 0;
+  for (int i = 0; i < n * 1024; i++) {
+    sum += i;
+    *(x++) = sum;
+  }
+  return ESP.getCycleCount() - b;
+}
+
 uint32_t cyclesToRead_nKx8(int n, unsigned char*x, uint32_t *res) {
   uint32_t b = ESP.getCycleCount();
   uint32_t sum = 0;

  return ESP.getCycleCount() - b;
}

uint32_t cyclesToRead_nKx8_viaInline(int n, unsigned char*x, uint32_t *res) {
  uint32_t b = ESP.getCycleCount();
  uint32_t sum = 0;

  return ESP.getCycleCount() - b;
}

bool perfTest_nK(int nK, uint32_t *mem, uint32_t *imem) {
  uint32_t res, verify_res;
  uint32_t t;
  bool success = true;
  int sres, verify_sres;

  Serial.printf("\r\nPerformance numbers for 16 bit access - using inline macros or exception handling for IRAM.\r\n");;
  t = cyclesToWrite_nKx16(nK, (uint16_t*)mem);
  Serial.printf("DRAM Memory Write:         %7d cycles for %dK by uint16, %3d AVG cycles/transfer\r\n", t, nK, t / (nK * 1024));
  t = cyclesToRead_nKx16(nK, (uint16_t*)mem, &verify_res);
  Serial.printf("DRAM Memory Read:          %7d cycles for %dK by uint16, %3d AVG cycles/transfer (sum %08x)\r\n", t, nK, t / (nK * 1024), verify_res);
  t = cyclesToWrite_nKxs16(nK, (int16_t*)mem);
  Serial.printf("DRAM Memory Write:         %7d cycles for %dK by  int16, %3d AVG cycles/transfer\r\n", t, nK, t / (nK * 1024));
  t = cyclesToRead_nKxs16(nK, (int16_t*)mem, &verify_sres);
  Serial.printf("DRAM Memory Read:          %7d cycles for %dK by  int16, %3d AVG cycles/transfer (sum %08x)\r\n", t, nK, t / (nK * 1024), verify_sres);

  t = cyclesToWrite_nKx16_viaInline(nK, (uint16_t*)imem);
  Serial.printf("IRAM Memory Write Inline:  %7d cycles for %dK by uint16, %3d AVG cycles/transfer\r\n", t, nK, t / (nK * 1024));
  t = cyclesToRead_nKx16_viaInline(nK, (uint16_t*)imem, &res);
  Serial.printf("IRAM Memory Read Inline:   %7d cycles for %dK by uint16, %3d AVG cycles/transfer (sum %08x) ", t, nK, t / (nK * 1024), res);
  if (res == verify_res) {
    Serial.printf("- passed\r\n");
  } else {
    Serial.printf("!= (sum %08x ) - failed\r\n", verify_res);
    success = false;
  }

  t = cyclesToWrite_nKxs16_viaInline(nK, (int16_t*)imem);
  Serial.printf("IRAM Memory Write Inline:  %7d cycles for %dK by  int16, %3d AVG cycles/transfer\r\n", t, nK, t / (nK * 1024));
  t = cyclesToRead_nKxs16_viaInline(nK, (int16_t*)imem, &sres);
  Serial.printf("IRAM Memory Read Inline:   %7d cycles for %dK by  int16, %3d AVG cycles/transfer (sum %08x) ", t, nK, t / (nK * 1024), sres);
  if (sres == verify_sres) {
    Serial.printf("- passed\r\n");
  } else {
    Serial.printf("!= (sum %08x ) - failed\r\n", verify_sres);
    success = false;
  }

  t = cyclesToWrite_nKx16(nK, (uint16_t*)imem);
  Serial.printf("IRAM Memory Write:         %7d cycles for %dK by uint16, %3d AVG cycles/transfer\r\n", t, nK, t / (nK * 1024));
  t = cyclesToRead_nKx16(nK, (uint16_t*)imem, &res);
  Serial.printf("IRAM Memory Read:          %7d cycles for %dK by uint16, %3d AVG cycles/transfer (sum %08x) ", t, nK, t / (nK * 1024), res);
  if (res == verify_res) {
    Serial.printf("- passed\r\n");
  } else {
    Serial.printf("!= (sum %08x ) - failed\r\n", verify_res);
    success = false;
  }
  t = cyclesToWrite_nKxs16(nK, (int16_t*)imem);
  Serial.printf("IRAM Memory Write:         %7d cycles for %dK by  int16, %3d AVG cycles/transfer\r\n", t, nK, t / (nK * 1024));
  t = cyclesToRead_nKxs16(nK, (int16_t*)imem, &sres);
  Serial.printf("IRAM Memory Read:          %7d cycles for %dK by  int16, %3d AVG cycles/transfer (sum %08x) ", t, nK, t / (nK * 1024), sres);
  if (sres == verify_sres) {
    Serial.printf("- passed\r\n");
  } else {
    Serial.printf("!= (sum %08x ) - failed\r\n", verify_sres);
    success = false;
  }

  Serial.printf("\r\nPerformance numbers for 8 bit access - using inline macros or exception handling for IRAM access.\r\n");;
  t = cyclesToWrite_nKx8(nK, (uint8_t*)mem);
  Serial.printf("DRAM Memory Write:         %7d cycles for %dK by  uint8, %3d AVG cycles/transfer\r\n", t, nK, t / (nK * 1024));
  t = cyclesToRead_nKx8(nK, (uint8_t*)mem, &verify_res);
  Serial.printf("DRAM Memory Read:          %7d cycles for %dK by  uint8, %3d AVG cycles/transfer (sum %08x)\r\n", t, nK, t / (nK * 1024), verify_res);

  t = cyclesToWrite_nKx8_viaInline(nK, (uint8_t*)imem);
  Serial.printf("IRAM Memory Write Inline:  %7d cycles for %dK by  uint8, %3d AVG cycles/transfer\r\n", t, nK, t / (nK * 1024));
  t = cyclesToRead_nKx8_viaInline(nK, (uint8_t*)imem, &res);
  Serial.printf("IRAM Memory Read Inline:   %7d cycles for %dK by  uint8, %3d AVG cycles/transfer (sum %08x) ", t, nK, t / (nK * 1024), res);
  if (res == verify_res) {
    Serial.printf("- passed\r\n");
  } else {
    Serial.printf("!= (sum %08x ) - failed\r\n", verify_res);
    success = false;
  }

  t = cyclesToWrite_nKx8(nK, (uint8_t*)imem);
  Serial.printf("IRAM Memory Write:         %7d cycles for %dK by  uint8, %3d AVG cycles/transfer\r\n", t, nK, t / (nK * 1024));
  t = cyclesToRead_nKx8(nK, (uint8_t*)imem, &res);
  Serial.printf("IRAM Memory Read:          %7d cycles for %dK by  uint8, %3d AVG cycles/transfer (sum %08x) ", t, nK, t / (nK * 1024), res);
  if (res == verify_res) {
    Serial.printf("- passed\r\n");
  } else {
    Serial.printf("!= (sum %08x ) - failed\r\n", verify_res);
    success = false;
  }
  Serial.println();

  return success;
}

void setup() {
