dawn_wire: Use memcpy in Serializer / Deserializer when possible
This patch uses memcpy to copy the arrays in basic types instead of iterating every elements in a for-loop. In the next step we will copy specific structures with memcpy. With this patch, the performance of dawn_perf_tests BufferUploadPerf.Run/*_WriteBuffer_BufferSize_* with "-w" will be greatly improved (~30%). BUG=chromium:1266727 Change-Id: I7c6fb0fafa63bd6b602eeef8cf2c0ae0cfc7b0be Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/71180 Reviewed-by: Corentin Wallez <cwallez@chromium.org> Reviewed-by: Austin Eng <enga@chromium.org> Commit-Queue: Jiawei Shao <jiawei.shao@intel.com>
This commit is contained in:
parent
3a036ab698
commit
6d6b63c470
|
@ -84,6 +84,7 @@ class Type:
|
|||
self.dict_name = name
|
||||
self.name = Name(name, native=native)
|
||||
self.category = json_data['category']
|
||||
self.is_wire_transparent = False
|
||||
|
||||
|
||||
EnumValue = namedtuple('EnumValue', ['name', 'value', 'valid', 'json_data'])
|
||||
|
@ -113,6 +114,7 @@ class EnumType(Type):
|
|||
raise Exception("Duplicate value {} in enum {}".format(
|
||||
value.value, name))
|
||||
all_values.add(value.value)
|
||||
self.is_wire_transparent = True
|
||||
|
||||
|
||||
BitmaskValue = namedtuple('BitmaskValue', ['name', 'value', 'json_data'])
|
||||
|
@ -128,6 +130,7 @@ class BitmaskType(Type):
|
|||
self.full_mask = 0
|
||||
for value in self.values:
|
||||
self.full_mask = self.full_mask | value.value
|
||||
self.is_wire_transparent = True
|
||||
|
||||
|
||||
class CallbackType(Type):
|
||||
|
@ -145,6 +148,7 @@ class TypedefType(Type):
|
|||
class NativeType(Type):
|
||||
def __init__(self, is_enabled, name, json_data):
|
||||
Type.__init__(self, name, json_data, native=True)
|
||||
self.is_wire_transparent = True
|
||||
|
||||
|
||||
# Methods and structures are both "records", so record members correspond to
|
||||
|
|
|
@ -269,12 +269,18 @@
|
|||
{{member_transfer_type(member)}}* memberBuffer;
|
||||
WIRE_TRY(buffer->NextN(memberLength, &memberBuffer));
|
||||
|
||||
{% if member.type.is_wire_transparent %}
|
||||
memcpy(
|
||||
memberBuffer, record.{{memberName}},
|
||||
{{member_transfer_sizeof(member)}} * memberLength);
|
||||
{% else %}
|
||||
//* This loop cannot overflow because it iterates up to |memberLength|. Even if
|
||||
//* memberLength were the maximum integer value, |i| would become equal to it just before
|
||||
//* exiting the loop, but not increment past or wrap around.
|
||||
//* memberLength were the maximum integer value, |i| would become equal to it
|
||||
//* just before exiting the loop, but not increment past or wrap around.
|
||||
for (decltype(memberLength) i = 0; i < memberLength; ++i) {
|
||||
{{serialize_member(member, "record." + memberName + "[i]", "memberBuffer[i]" )}}
|
||||
}
|
||||
{% endif %}
|
||||
}
|
||||
{% endfor %}
|
||||
return WireResult::Success;
|
||||
|
@ -392,12 +398,23 @@
|
|||
record->{{memberName}} = copiedMembers;
|
||||
{% endif %}
|
||||
|
||||
{% if member.type.is_wire_transparent %}
|
||||
//* memcpy is not allowed to copy from volatile objects. However, these arrays
|
||||
//* are just used as plain data, and don't impact control flow. So if the
|
||||
//* underlying data were changed while the copy was still executing, we would
|
||||
//* get different data - but it wouldn't cause unexpected downstream effects.
|
||||
memcpy(
|
||||
copiedMembers,
|
||||
const_cast<const {{member_transfer_type(member)}}*>(memberBuffer),
|
||||
{{member_transfer_sizeof(member)}} * memberLength);
|
||||
{% else %}
|
||||
//* This loop cannot overflow because it iterates up to |memberLength|. Even if
|
||||
//* memberLength were the maximum integer value, |i| would become equal to it just before
|
||||
//* exiting the loop, but not increment past or wrap around.
|
||||
//* memberLength were the maximum integer value, |i| would become equal to it
|
||||
//* just before exiting the loop, but not increment past or wrap around.
|
||||
for (decltype(memberLength) i = 0; i < memberLength; ++i) {
|
||||
{{deserialize_member(member, "memberBuffer[i]", "copiedMembers[i]")}}
|
||||
}
|
||||
{% endif %}
|
||||
}
|
||||
{% endfor %}
|
||||
|
||||
|
|
Loading…
Reference in New Issue