Reduce MITC4 Jet product scratch stack storage
This commit is contained in:
@@ -594,17 +594,17 @@ Jet operator*(const Jet& left, const Jet& right) {
|
|||||||
const bool masked_exceptions =
|
const bool masked_exceptions =
|
||||||
(_mm_getcsr() & _MM_MASK_MASK) == _MM_MASK_MASK;
|
(_mm_getcsr() & _MM_MASK_MASK) == _MM_MASK_MASK;
|
||||||
const bool outer_accepted = Outer(left.first, right.first, result_second);
|
const bool outer_accepted = Outer(left.first, right.first, result_second);
|
||||||
|
std::array<double, kHessianSize> scratch;
|
||||||
if (masked_exceptions && outer_accepted) {
|
if (masked_exceptions && outer_accepted) {
|
||||||
// Retain earlier upper entries for later lower entries before overwriting
|
// Retain earlier upper entries for later lower entries before overwriting
|
||||||
// them. Reuse the MKL k=1 transpose while preserving the original row-major
|
// them. Reuse the MKL k=1 transpose while preserving the original row-major
|
||||||
// arithmetic order as well as each entry's four-term association.
|
// arithmetic order as well as each entry's four-term association.
|
||||||
std::array<double, kGlobalDofCount * (kGlobalDofCount - 1U) / 2U> upper;
|
|
||||||
std::size_t saved = 0U;
|
std::size_t saved = 0U;
|
||||||
for (std::size_t row = 0U; row < kGlobalDofCount; ++row) {
|
for (std::size_t row = 0U; row < kGlobalDofCount; ++row) {
|
||||||
for (std::size_t column = 0U; column < row; ++column) {
|
for (std::size_t column = 0U; column < row; ++column) {
|
||||||
const std::size_t index = row * kGlobalDofCount + column;
|
const std::size_t index = row * kGlobalDofCount + column;
|
||||||
result_second[index] = left_second[index] * right.value +
|
result_second[index] = left_second[index] * right.value +
|
||||||
result_second[index] + upper[saved++] +
|
result_second[index] + scratch[saved++] +
|
||||||
left.value * right_second[index];
|
left.value * right_second[index];
|
||||||
}
|
}
|
||||||
const std::size_t diagonal = row * kGlobalDofCount + row;
|
const std::size_t diagonal = row * kGlobalDofCount + row;
|
||||||
@@ -616,7 +616,7 @@ Jet operator*(const Jet& left, const Jet& right) {
|
|||||||
const std::size_t transpose = column * kGlobalDofCount + row;
|
const std::size_t transpose = column * kGlobalDofCount + row;
|
||||||
const double forward = result_second[index];
|
const double forward = result_second[index];
|
||||||
const double reverse = result_second[transpose];
|
const double reverse = result_second[transpose];
|
||||||
upper[column * (column - 1U) / 2U + row] = forward;
|
scratch[column * (column - 1U) / 2U + row] = forward;
|
||||||
result_second[index] = left_second[index] * right.value +
|
result_second[index] = left_second[index] * right.value +
|
||||||
forward + reverse + left.value * right_second[index];
|
forward + reverse + left.value * right_second[index];
|
||||||
}
|
}
|
||||||
@@ -624,13 +624,12 @@ Jet operator*(const Jet& left, const Jet& right) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
// Preserve the reverse input-validation order after a rejected first outer.
|
// Preserve the reverse input-validation order after a rejected first outer.
|
||||||
std::array<double, kHessianSize> reverse;
|
Outer(right.first, left.first, scratch.data());
|
||||||
Outer(right.first, left.first, reverse.data());
|
|
||||||
for (std::size_t row = 0U; row < kGlobalDofCount; ++row) {
|
for (std::size_t row = 0U; row < kGlobalDofCount; ++row) {
|
||||||
for (std::size_t column = 0U; column < kGlobalDofCount; ++column) {
|
for (std::size_t column = 0U; column < kGlobalDofCount; ++column) {
|
||||||
const std::size_t index = row * kGlobalDofCount + column;
|
const std::size_t index = row * kGlobalDofCount + column;
|
||||||
result_second[index] = left_second[index] * right.value +
|
result_second[index] = left_second[index] * right.value +
|
||||||
result_second[index] + reverse[index] +
|
result_second[index] + scratch[index] +
|
||||||
left.value * right_second[index];
|
left.value * right_second[index];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,9 +63,19 @@ SEH/process 관측이나 생성 코드 근거가 필요하며, source의 row-maj
|
|||||||
T2의 무가드 단일 외적 후보는 unmasked 최초 INVALID/OVERFLOW 순서가 달라 비채택했다.
|
T2의 무가드 단일 외적 후보는 unmasked 최초 INVALID/OVERFLOW 순서가 달라 비채택했다.
|
||||||
채택한 guarded 경로는 MXCSR의 여섯 예외가 모두 masked이고 첫 외적이 성공한 경우에만
|
채택한 guarded 경로는 MXCSR의 여섯 예외가 모두 masked이고 첫 외적이 성공한 경우에만
|
||||||
전치 성분과 276개 상삼각 scratch를 재사용한다. Unmasked 환경과 외적 거부는 기존 두 호출,
|
전치 성분과 276개 상삼각 scratch를 재사용한다. Unmasked 환경과 외적 거부는 기존 두 호출,
|
||||||
576개 reverse 배열과 row-major 결합을 유지한다. Masked snapshot과 별도 원본/후보 SEH
|
576개 reverse 외적과 row-major 결합을 유지한다. Masked snapshot과 별도 원본/후보 SEH
|
||||||
관측을 함께 확인하며, 정상 경로의 임시 쓰기 감소를 전체 stack 예약 감소로 보고하지 않는다.
|
관측을 함께 확인하며, 정상 경로의 임시 쓰기 감소를 전체 stack 예약 감소로 보고하지 않는다.
|
||||||
|
|
||||||
|
T5는 서로 배타적인 276개 상삼각 보관과 576개 reverse 외적에 같은 local
|
||||||
|
`std::array<double, 576>` scratch를 사용한다. 입력·공유 Hessian의 저장소와 수명은
|
||||||
|
바꾸지 않는다. 두 분기에서 쓰기 전 읽기가 없는지 검토하고 위 3구성 비교 및 별도
|
||||||
|
6개 unmasked 최초 trap을 확인한다. Stack 예약량은 실제 Release production object의
|
||||||
|
frame과 `__chkstk`를 확인하며, heap 할당 감소나 전체 모델 속도 향상으로 해석하지 않는다.
|
||||||
|
별도 복사 source의 Values 생성·소멸 계측은 생존 시작량을 포함한 peak payload와
|
||||||
|
증가량을 구분한다. 동시 호출 peak는 스케줄에 따라 달라지고, 계측 시간은 정상 Release
|
||||||
|
측정에서 제외한다. Hessian 복사 연산 횟수는 implicit/null 복사도 포함하며 strong-ref
|
||||||
|
증가 횟수나 CPU 비용을 뜻하지 않는다. Global pool이나 trial 간 cache는 도입하지 않는다.
|
||||||
|
|
||||||
T3 누적 검사는 기존 T1/T2 snapshot을 확장하지 않고 별도 파일을 쓴다. 원본 source와
|
T3 누적 검사는 기존 T1/T2 snapshot을 확장하지 않고 별도 파일을 쓴다. 원본 source와
|
||||||
보존 archive의 출처를 확인한 실행물에서만 새 경로에 생성한다. 실제 CMake 경로는
|
보존 archive의 출처를 확인한 실행물에서만 새 경로에 생성한다. 실제 CMake 경로는
|
||||||
원본 source staging을 CMake로 configure/build한 실행물과 구분해 연결한다.
|
원본 source staging을 CMake로 configure/build한 실행물과 구분해 연결한다.
|
||||||
|
|||||||
Reference in New Issue
Block a user