@@ -36,6 +36,7 @@ limitations under the License.
36
36
#include " absl/algorithm/container.h"
37
37
#include " absl/container/flat_hash_map.h"
38
38
#include " absl/container/flat_hash_set.h"
39
+ #include " absl/container/inlined_vector.h"
39
40
#include " absl/functional/any_invocable.h"
40
41
#include " absl/log/check.h"
41
42
#include " absl/log/log.h"
@@ -3129,8 +3130,16 @@ bool AsynchronousCopyOrdering::ViolatesOrdering(int64_t exclusive_start_time,
3129
3130
3130
3131
bool AsynchronousCopyResource::ConsumeResource (
3131
3132
int64_t exclusive_start_time, int64_t end_time, float resource,
3132
- absl::flat_hash_map< int64_t , float >* delay_change_map ,
3133
+ std::vector<std::pair< int64_t , float >>* delay_changes ,
3133
3134
float resource_to_free) {
3135
+ // Cache the pointers to the arrays to avoid the overhead of `operator[]`
3136
+ // size checks in hardened libc++.
3137
+ //
3138
+ // NOTE: Do not modify the vectors `initial_resources_` or `delay_` in this
3139
+ // function, otherwise the pointers will become dangling.
3140
+ float * initial_resources_ptr = initial_resources_.data ();
3141
+ float * delay_ptr = delay_.data ();
3142
+
3134
3143
std::list<AsynchronousCopy>::iterator current_copy = async_copies_.end ();
3135
3144
// In order to propagate the resource to the next scheduled copy, we iterate
3136
3145
// over the copies in start time order until we either find enough free
@@ -3160,7 +3169,8 @@ bool AsynchronousCopyResource::ConsumeResource(
3160
3169
// this copy would have to be delayed because of an earlier copy that wasn't
3161
3170
// finished when this copy starts.
3162
3171
if (current_copy == async_copies_.end ()) {
3163
- resource += delay_[ExclusiveToInclusiveStartTime (exclusive_start_time)];
3172
+ resource +=
3173
+ delay_ptr[ExclusiveToInclusiveStartTime (exclusive_start_time)];
3164
3174
}
3165
3175
3166
3176
// Find the copy that is right after this one. If there are leftover
@@ -3186,7 +3196,7 @@ bool AsynchronousCopyResource::ConsumeResource(
3186
3196
time < end_time && resource != 0 ; ++time ) {
3187
3197
// Iterate over the logical times that this copy spans. Note that the
3188
3198
// start and end time ranges are exclusive.
3189
- float used_resource = std::min (resource, initial_resources_ [time ]);
3199
+ float used_resource = std::min (resource, initial_resources_ptr [time ]);
3190
3200
if (next_copy != async_copies_.end () &&
3191
3201
next_copy->exclusive_start_time ==
3192
3202
InclusiveToExclusiveStartTime (time )) {
@@ -3199,15 +3209,17 @@ bool AsynchronousCopyResource::ConsumeResource(
3199
3209
if (!delay_for_next_copy.has_value ()) {
3200
3210
// Update the delay_ vector and resource_freed variable with the amount
3201
3211
// that was freed when removing the copy.
3212
+ float old_delay = delay_ptr[time ];
3202
3213
float old_resource =
3203
- std::max (0 .0f , initial_resources_[time ] - delay_[time ]);
3204
- if (delay_change_map) {
3205
- delay_change_map->emplace (time , delay_[time ]);
3206
- }
3207
- delay_[time ] = std::max (0 .0f , resource - resource_to_free);
3214
+ std::max (0 .0f , initial_resources_ptr[time ] - old_delay);
3215
+ float new_delay = std::max (0 .0f , resource - resource_to_free);
3208
3216
float new_resource =
3209
- std::max (0 .0f , initial_resources_ [time ] - delay_[ time ] );
3217
+ std::max (0 .0f , initial_resources_ptr [time ] - new_delay );
3210
3218
resource_freed += std::max (0 .0f , new_resource - old_resource);
3219
+ delay_ptr[time ] = new_delay;
3220
+ if (delay_changes) {
3221
+ delay_changes->emplace_back (time , old_delay);
3222
+ }
3211
3223
}
3212
3224
// Update the resource with the used amount in this logical time.
3213
3225
resource -= used_resource;
@@ -3303,7 +3315,7 @@ void AsynchronousCopyResource::RemoveCopy(
3303
3315
copy_it->exclusive_start_time );
3304
3316
CHECK (ConsumeResource (copy_it->exclusive_start_time , copy_it->end_time ,
3305
3317
/* resource=*/ 0 ,
3306
- /* delay_change_map =*/ nullptr ,
3318
+ /* delay_changes =*/ nullptr ,
3307
3319
/* resource_to_free=*/ copy_it->resource ));
3308
3320
// If the copy to be removed is the value pointed by async_copy_time_map_, we
3309
3321
// make the next copy with the same start time to be pointed by
@@ -3325,24 +3337,36 @@ void AsynchronousCopyResource::RemoveCopy(
3325
3337
bool AsynchronousCopyResource::HasEnoughResource (int64_t exclusive_start_time,
3326
3338
int64_t end_time,
3327
3339
float resource) {
3328
- absl::flat_hash_map<int64_t , float > delay_changes;
3340
+ std::vector<std::pair<int64_t , float >> delay_changes;
3341
+ delay_changes.reserve (delay_.size ());
3329
3342
bool result =
3330
3343
ConsumeResource (exclusive_start_time, end_time, resource, &delay_changes);
3331
- for (const auto & change_pair : delay_changes) {
3332
- delay_[change_pair.first ] = change_pair.second ;
3344
+ // Apply the delay changes in reverse order. This ensures that the original
3345
+ // value of each delay is restored.
3346
+ if (!delay_changes.empty ()) {
3347
+ for (int64_t i = delay_changes.size () - 1 ; i >= 0 ; --i) {
3348
+ const auto & [time , delay] = delay_changes[i];
3349
+ delay_[time ] = delay;
3350
+ }
3333
3351
}
3334
3352
return result;
3335
3353
}
3336
3354
3337
3355
bool AsynchronousCopyResource::HasEnoughResourceMultiCheck (
3338
3356
const std::vector<ResourceSpec>& specs) {
3339
- absl::flat_hash_map<int64_t , float > delay_changes;
3357
+ std::vector<std::pair<int64_t , float >> delay_changes;
3358
+ delay_changes.reserve (delay_.size ());
3340
3359
bool result = absl::c_all_of (specs, [&](const ResourceSpec& spec) {
3341
3360
return ConsumeResource (spec.exclusive_start_time , spec.end_time ,
3342
3361
spec.resource , &delay_changes);
3343
3362
});
3344
- for (const auto & change_pair : delay_changes) {
3345
- delay_[change_pair.first ] = change_pair.second ;
3363
+ // Apply the delay changes in reverse order. This ensures that the original
3364
+ // value of each delay is restored.
3365
+ if (!delay_changes.empty ()) {
3366
+ for (int64_t i = delay_changes.size () - 1 ; i >= 0 ; --i) {
3367
+ const auto & [time , delay] = delay_changes[i];
3368
+ delay_[time ] = delay;
3369
+ }
3346
3370
}
3347
3371
return result;
3348
3372
}
0 commit comments