DataLoopTest.cpp 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. 
  2. #include "../testTools.h"
  3. #include "../../DFPSR/base/simd.h"
  4. #define INITIALIZE \
  5. for (int i = 0; i < elements; i++) { \
  6. bufferA[i] = i % 13; \
  7. bufferB[i] = i % 7; \
  8. bufferC[i] = 0; \
  9. }
  10. #define CHECK_RESULT \
  11. { \
  12. int errors = 0; \
  13. for (int i = 0; i < elements; i++) { \
  14. if (bufferC[i] != ((i % 13) * (i % 7)) + 5) { \
  15. errors++; \
  16. } \
  17. } \
  18. ASSERT_EQUAL(errors, 0); \
  19. }
  20. START_TEST(DataLoop)
  21. // Allocate aligned memory
  22. const int elements = 256;
  23. ALIGN16 int32_t allocationA[elements];
  24. ALIGN16 int32_t allocationB[elements];
  25. ALIGN16 int32_t allocationC[elements];
  26. // The SafePointer class will emulate the behaviour of a raw data pointer while providing full bound checks in debug mode.
  27. SafePointer<int32_t> bufferA("bufferA", allocationA, sizeof(allocationA));
  28. SafePointer<int32_t> bufferB("bufferB", allocationB, sizeof(allocationB));
  29. SafePointer<int32_t> bufferC("bufferC", allocationC, sizeof(allocationC));
  30. // Calculate C = (A * B) + 5
  31. { // Reference implementation
  32. INITIALIZE;
  33. for (int i = 0; i < elements; i++) {
  34. bufferC[i] = (bufferA[i] * bufferB[i]) + 5;
  35. }
  36. CHECK_RESULT;
  37. }
  38. { // Pointer version
  39. INITIALIZE;
  40. // Iterating pointers are created from the main pointers
  41. SafePointer<int32_t> ptrA = bufferA;
  42. SafePointer<int32_t> ptrB = bufferB;
  43. SafePointer<int32_t> ptrC = bufferC;
  44. for (int i = 0; i < elements; i++) {
  45. // *a is the same as a[0]
  46. *ptrC = *ptrA * *ptrB + 5;
  47. // Adding one to a pointer adds the size of the element type
  48. ptrA += 1;
  49. ptrB += 1;
  50. ptrC += 1;
  51. }
  52. CHECK_RESULT;
  53. }
  54. { // Pseudo vectorization (what the SIMD math actually means)
  55. INITIALIZE;
  56. for (int i = 0; i < elements - 3; i += 4) {
  57. bufferC[i + 0] = (bufferA[i + 0] * bufferB[i + 0]) + 5;
  58. bufferC[i + 1] = (bufferA[i + 1] * bufferB[i + 1]) + 5;
  59. bufferC[i + 2] = (bufferA[i + 2] * bufferB[i + 2]) + 5;
  60. bufferC[i + 3] = (bufferA[i + 3] * bufferB[i + 3]) + 5;
  61. }
  62. CHECK_RESULT;
  63. }
  64. { // SIMD version
  65. INITIALIZE;
  66. SafePointer<int32_t> ptrA = bufferA;
  67. SafePointer<int32_t> ptrB = bufferB;
  68. SafePointer<int32_t> ptrC = bufferC;
  69. for (int i = 0; i < elements - 3; i += 4) {
  70. // Read vectors
  71. I32x4 a = I32x4::readAligned(ptrA, "data loop test @ read a");
  72. I32x4 b = I32x4::readAligned(ptrB, "data loop test @ read b");
  73. // Do the calculation with 4 elements at once from i to i + 3 using SIMD operations
  74. I32x4 result = a * b + 5;
  75. // Write the result
  76. result.writeAligned(ptrC, "data loop test @ write c");
  77. // Iterate pointers
  78. ptrA += 4;
  79. ptrB += 4;
  80. ptrC += 4;
  81. }
  82. CHECK_RESULT;
  83. }
  84. END_TEST